Esempio n. 1
0
        private string GetExistingUserProfile(string username, string password, string userSID = "")
        {
            Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
            if (String.IsNullOrEmpty(userSID))
            {
                if (!Abstractions.WindowsApi.pInvokes.UserGet(username, ref userinfo4))
                {
                    m_logger.DebugFormat("Can't get userinfo for user {0}", username);
                    return("");
                }
                try
                {
                    userSID = new SecurityIdentifier(userinfo4.user_sid).Value;
                }
                catch (Exception ex)
                {
                    m_logger.ErrorFormat("failed to convert SID for \"{0}\":{1}", userinfo4.name, ex.ToString());
                    return("");
                }
            }

            m_logger.InfoFormat("SID found:{0}", userSID);
            if (!Abstractions.Windows.User.FixProfileList(userSID))
            {
                m_logger.DebugFormat("Error in FixProfileList {0}", userSID);
            }

            return(Abstractions.Windows.User.GetProfileDir(username, password, new SecurityIdentifier(userSID)));
        }
Esempio n. 2
0
        public Boolean userAdd(Dictionary <string, string> settings, string username, string password, string comment)
        {
            Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();

            //create user
            if (!Abstractions.WindowsApi.pInvokes.UserExists(username))
            {
                if (!Abstractions.WindowsApi.pInvokes.UserADD(username, password, comment))
                {
                    m_logger.DebugFormat("Can't add user {0}", username);
                    return(false);
                }
            }

            //get userinfo
            if (!Abstractions.WindowsApi.pInvokes.UserGet(username, ref userinfo4))
            {
                m_logger.DebugFormat("Can't get userinfo for user {0}", username);
                return(false);
            }

            //fill userinfo
            userinfo4.profile = null;
            if (!String.IsNullOrEmpty(settings["HomeDir"]))
            {
                userinfo4.home_dir = settings["HomeDir"];
            }
            if (!String.IsNullOrEmpty(settings["HomeDirDrive"]))
            {
                userinfo4.home_dir_drive = settings["HomeDirDrive"];
            }
            if (!String.IsNullOrEmpty(settings["ScriptPath"]))
            {
                userinfo4.script_path = null;
            }
            //userinfo4.script_path = settings["ScriptPath"];

            /*if (Convert.ToInt32(settings["MaxStore"]) > 0)
             *  userinfo4.max_storage = Convert.ToInt32(settings["MaxStore"]);
             * else
             *  userinfo4.max_storage = -1;*/
            userinfo4.password     = password;
            userinfo4.comment      = comment;
            userinfo4.flags       |= Abstractions.WindowsApi.pInvokes.structenums.UserFlags.UF_NORMAL_ACCOUNT;
            userinfo4.acct_expires = -1;
            userinfo4.logon_hours  = IntPtr.Zero;

            //apply userinfo
            if (!Abstractions.WindowsApi.pInvokes.UserMod(username, userinfo4))
            {
                m_logger.DebugFormat("Can't modify user {0}", username);
                return(false);
            }
            m_logger.InfoFormat("user {0} created", username);

            return(true);
        }
Esempio n. 3
0
        private Boolean SetACL(string dir, string username, string password, uint maxstore, uint retry)
        {
            m_logger.InfoFormat("modify ACE");

            Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
            if (!Abstractions.WindowsApi.pInvokes.UserGet(username, ref userinfo4))
            {
                m_logger.DebugFormat("Can't get userinfo for user {0}", username);
                return(false);
            }

            IdentityReference userIref = new SecurityIdentifier(userinfo4.user_sid).Translate(typeof(NTAccount));

            if (!Abstractions.Windows.Security.SetDirOwner(dir, new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).Translate(typeof(NTAccount))))
            {
                m_logger.WarnFormat("Can't set owner for Directory {0}", dir);
                return(false);
            }

            if (!Abstractions.Windows.Security.ReplaceDirectorySecurity(dir, new IdentityReference[] { new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null), new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null), userIref }, FileSystemRights.FullControl, AccessControlType.Allow, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None))
            {
                m_logger.WarnFormat("Can't set ACL for Directory {0}", dir);
                return(false);
            }

            if (!Abstractions.Windows.Security.RemoveAccRuleFromUnknownUser(dir))
            {
                m_logger.InfoFormat("Can't remove unknown users from {0} ACL", dir);
                //not critical
            }

            if (!SetACLquotaREGfile(dir + "\\NTUSER.DAT", retry, username, maxstore, true, true))
            {
                return(false);
            }
            if (File.Exists(dir + @"\AppData\Local\Microsoft\Windows\UsrClass.dat"))
            {
                if (!SetACLquotaREGfile(dir + @"\AppData\Local\Microsoft\Windows\UsrClass.dat", retry, username, maxstore, false, true))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 4
0
        private Boolean UserCanBeUsed(string username)
        {
            Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();

            //get userinfo
            if (!Abstractions.WindowsApi.pInvokes.UserGet(username, ref userinfo4))
            {
                return(true);
            }

            //check if this is a pgina user
            if (userinfo4.comment.Contains("pGina created pgSMB2"))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Esempio n. 5
0
        private Boolean CreateRoamingFolder(string dir, string username)
        {
            if (!Directory.Exists(dir))
            {
                try
                {
                    Directory.CreateDirectory(dir);
                }
                catch
                {
                    m_logger.WarnFormat("Can't create Directory {0}", dir);
                    return(false);
                }
            }

            Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
            if (!Abstractions.WindowsApi.pInvokes.UserGet(username, ref userinfo4))
            {
                m_logger.WarnFormat("Can't get userinfo4 from {0}", username);
                return(false);
            }

            IdentityReference userIref = new SecurityIdentifier(userinfo4.user_sid).Translate(typeof(NTAccount));

            if (!Abstractions.Windows.Security.SetDirOwner(dir, new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).Translate(typeof(NTAccount))))
            {
                m_logger.WarnFormat("Can't set owner {0} for Directory {1}", username, dir);
                return(false);
            }

            if (!Abstractions.Windows.Security.SetDirectorySecurity(dir, new IdentityReference[] { userIref }, FileSystemRights.Write | FileSystemRights.ReadAndExecute, AccessControlType.Allow, InheritanceFlags.None, PropagationFlags.None))
            {
                m_logger.WarnFormat("Can't set ACL for Directory {0}", dir);
                return(false);
            }

            return(true);
        }
Esempio n. 6
0
        public BooleanResult AuthenticatedUserGateway(SessionProperties properties)
        {
            // Our job, if we've been elected to do gateway, is to ensure that an
            //  authenticated user:
            //
            //  1. Has a local account
            //  2. That account's password is set to the one they used to authenticate
            //  3. That account is a member of all groups listed, and not a member of any others

            // Is failure at #3 a total fail?
            bool failIfGroupSyncFails = Settings.Store.GroupCreateFailIsFail;

            // Groups everyone is added to
            string[] MandatoryGroups = Settings.Store.MandatoryGroups;

            // user info
            UserInformation userInfo = properties.GetTrackedSingle <UserInformation>();

            // is this a pgina user?
            Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
            if (Abstractions.WindowsApi.pInvokes.UserGet(userInfo.Username, ref userinfo4)) //true if user exists
            {
                if (!userinfo4.comment.Contains("pGina created"))
                {
                    m_logger.InfoFormat("User {0} is'nt a pGina created user. I'm not executing Gateway stage", userInfo.Username);
                    return(new BooleanResult()
                    {
                        Success = true
                    });
                }
            }

            // Add user to all mandatory groups
            if (MandatoryGroups.Length > 0)
            {
                foreach (string group in MandatoryGroups)
                {
                    string group_string = group;

                    m_logger.DebugFormat("Is there a Group with SID/Name:{0}", group);
                    using (GroupPrincipal groupconf = LocalAccount.GetGroupPrincipal(group))
                    {
                        if (groupconf != null)
                        {
                            m_logger.DebugFormat("Groupname: \"{0}\"", groupconf.Name);
                            group_string = groupconf.Name;
                        }
                        else
                        {
                            m_logger.ErrorFormat("Group: \"{0}\" not found", group);
                            m_logger.Error("Failsave add user to group Users");
                            using (GroupPrincipal groupfail = LocalAccount.GetGroupPrincipal(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null).ToString()))
                            {
                                if (groupfail != null)
                                {
                                    group_string = groupfail.Name;
                                }
                                else
                                {
                                    m_logger.Debug("no BuiltinUsers. I'm out of options");
                                    group_string = null;
                                }
                            }
                        }
                    }

                    if (group_string != null)
                    {
                        userInfo.AddGroup(new GroupInformation()
                        {
                            Name = group_string
                        });
                    }
                }
            }

            try
            {
                m_logger.DebugFormat("AuthenticatedUserGateway({0}) for user: {1}", properties.Id.ToString(), userInfo.Username);
                LocalAccount.SyncUserInfoToLocalUser(userInfo);
                using (UserPrincipal user = LocalAccount.GetUserPrincipal(userInfo.Username))
                {
                    userInfo.SID         = user.Sid;
                    userInfo.Description = user.Description;
                }
                properties.AddTrackedSingle <UserInformation>(userInfo);
            }
            catch (LocalAccount.GroupSyncException e)
            {
                if (failIfGroupSyncFails)
                {
                    return new BooleanResult()
                           {
                               Success = false, Message = string.Format("Unable to sync users local group membership: {0}", e.RootException)
                           }
                }
                ;
            }
            catch (Exception e)
            {
                if (e.Message.ToLower().Contains("0x800708c5"))
                {
                    return(new BooleanResult()
                    {
                        Success = false, Message = string.Format("This Worstation is denying the password of {0}.\nMost likely the password does not meet complexity requirements\n\n{1}", userInfo.Username, e)
                    });
                }

                return(new BooleanResult()
                {
                    Success = false, Message = string.Format("Unexpected error while syncing user's info: {0}", e)
                });
            }

            return(new BooleanResult()
            {
                Success = true
            });
        }
Esempio n. 7
0
        private LoginResponseMessage HandleLoginRequest(LoginRequestMessage msg)
        {
            try
            {
                PluginDriver sessionDriver = new PluginDriver();
                bool LastUsernameEnable = Settings.Get.LastUsernameEnable;

                msg = SplitDomainfromUsername(msg);
                sessionDriver.UserInformation.Username = msg.Username;
                sessionDriver.UserInformation.Password = (String.IsNullOrEmpty(msg.Password)) ? "" : msg.Password;
                sessionDriver.UserInformation.Domain = msg.Domain;
                sessionDriver.UserInformation.SessionID = msg.Session;
                if (msg.Reason == LoginRequestMessage.LoginReason.CredUI)
                {
                    sessionDriver.SessionProperties.CREDUI = true;
                }

                if (String.IsNullOrEmpty(sessionDriver.UserInformation.Username))
                {
                    return new LoginResponseMessage() { Result = false, Message = String.Format("No Username supplied\n\n'{0}' was entered and parsed to '{1}'", msg.Username, sessionDriver.UserInformation.Username) };
                }

                // check if a plugin still does some logoff work for this user
                Boolean thisUserLogoff = false;
                foreach (IPluginLogoffRequestAddTime plugin in PluginLoader.GetOrderedPluginsOfType<IPluginLogoffRequestAddTime>())
                {
                    if (plugin.LoginUserRequest(sessionDriver.UserInformation.Username))
                        thisUserLogoff = true;
                }
                if (thisUserLogoff)
                {
                    return new LoginResponseMessage() { Result = false, Message = String.Format("Still logoff work to do for user {0}\nWait a view seconds and retry", sessionDriver.UserInformation.Username) };
                }

                // do the domain logon
                string domainmember = Abstractions.WindowsApi.pInvokes.GetMachineDomainMembershipEX();
                m_logger.InfoFormat("domain check:[{0}] [{1}] [{2}]", Regex.IsMatch(msg.Username, "\\|@"), !String.IsNullOrEmpty(domainmember), !sessionDriver.UserInformation.Domain.Equals(Environment.MachineName, StringComparison.CurrentCultureIgnoreCase));
                if ((Regex.IsMatch(msg.Username, "\\|@") || !String.IsNullOrEmpty(domainmember)) && !sessionDriver.UserInformation.Domain.Equals(Environment.MachineName, StringComparison.CurrentCultureIgnoreCase))
                {
                    m_logger.DebugFormat("domain logon: Username:{0} domainmember:{1} domain:{2}", msg.Username, domainmember, sessionDriver.UserInformation.Domain);
                    // if domain was provided by username and it got messed up ...
                    if (String.IsNullOrEmpty(sessionDriver.UserInformation.Domain) && Regex.IsMatch(msg.Username, "\\|@"))
                    {
                        return new LoginResponseMessage() { Result = false, Message = String.Format("No Domainname supplied\n\n'{0}' was entered and parsed to '{1}'", msg.Username, sessionDriver.UserInformation.Domain) };
                    }

                    if (Abstractions.WindowsApi.pInvokes.DomainMember(sessionDriver.UserInformation.Domain))
                    {
                        m_logger.InfoFormat("DomainMember");
                        // pc is member of this domain provided by the username field
                        if (Abstractions.WindowsApi.pInvokes.ValidateUser(sessionDriver.UserInformation.Username, sessionDriver.UserInformation.Domain, sessionDriver.UserInformation.Password))
                        {
                            if (LastUsernameEnable && msg.Reason == LoginRequestMessage.LoginReason.Login)
                            {
                                Settings.s_settings.SetSetting("LastUsername", String.Format("{0}\\{1}", sessionDriver.UserInformation.Domain, sessionDriver.UserInformation.Username));
                            }
                            m_logger.InfoFormat("Sucess");
                            return new LoginResponseMessage()
                            {
                                Result = true,
                                Message = "",
                                Username = sessionDriver.UserInformation.Username,
                                Domain = sessionDriver.UserInformation.Domain,
                                Password = sessionDriver.UserInformation.Password
                            };
                        }
                        else
                        {
                            string message = String.Format("The provided account:{0} name does not exist on:{1} or the password is wrong", sessionDriver.UserInformation.Username, sessionDriver.UserInformation.Domain);
                            m_logger.InfoFormat(message);
                            return new LoginResponseMessage()
                            {
                                Result = false,
                                Message = message,
                                Username = sessionDriver.UserInformation.Username,
                                Domain = sessionDriver.UserInformation.Domain,
                                Password = sessionDriver.UserInformation.Password
                            };
                        }
                    }
                    else if (!String.IsNullOrEmpty(domainmember))
                    {
                        m_logger.InfoFormat("GetMachineDomainMembership");
                        // pc is member of a domain
                        sessionDriver.UserInformation.Domain = domainmember;
                        if (Abstractions.WindowsApi.pInvokes.ValidateUser(sessionDriver.UserInformation.Username, sessionDriver.UserInformation.Domain, sessionDriver.UserInformation.Password))
                        {
                            if (LastUsernameEnable && msg.Reason == LoginRequestMessage.LoginReason.Login)
                            {
                                Settings.s_settings.SetSetting("LastUsername", String.Format("{0}\\{1}", sessionDriver.UserInformation.Domain, sessionDriver.UserInformation.Username));
                            }
                            m_logger.InfoFormat("Sucess");
                            return new LoginResponseMessage()
                            {
                                Result = true,
                                Message = "",
                                Username = sessionDriver.UserInformation.Username,
                                Domain = sessionDriver.UserInformation.Domain,
                                Password = sessionDriver.UserInformation.Password
                            };
                        }
                        else
                        {
                            m_logger.InfoFormat("Failed, query Remote({0}) SAM", domainmember);
                            sessionDriver.UserInformation.Domain = Environment.MachineName;
                        }
                    }
                }

                BooleanResult result = new BooleanResult() { Success = true, Message = "" };

                if (new[] { LoginRequestMessage.LoginReason.Login, LoginRequestMessage.LoginReason.CredUI }.Contains(msg.Reason))
                {
                    m_logger.DebugFormat("Processing LoginRequest for: {0} in session: {1} reason: {2}", sessionDriver.UserInformation.Username, msg.Session, msg.Reason);

                    Boolean isLoggedIN = false;
                    Boolean isUACLoggedIN = false;

                    // is this user a local user and was not created by pGina
                    Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
                    if (Abstractions.WindowsApi.pInvokes.UserGet(sessionDriver.UserInformation.Username, ref userinfo4))
                    {
                        if (!userinfo4.comment.Contains("pGina created"))
                        {
                            result.Success = Abstractions.WindowsApi.pInvokes.ValidateUser(sessionDriver.UserInformation.Username, sessionDriver.UserInformation.Domain, sessionDriver.UserInformation.Password);
                            if (result.Success)
                            {
                                if (LastUsernameEnable && msg.Reason == LoginRequestMessage.LoginReason.Login)
                                {
                                    Settings.s_settings.SetSetting("LastUsername", String.Format("{0}", sessionDriver.UserInformation.Username));
                                }
                            }
                            return new LoginResponseMessage()
                            {
                                Result = result.Success,
                                Message = (result.Success) ? "Local non pGina user" : "Unknown username or bad password",
                                Username = sessionDriver.UserInformation.Username,
                                Domain = sessionDriver.UserInformation.Domain,
                                Password = sessionDriver.UserInformation.Password
                            };
                        }
                    }

                    Dictionary<int, List<string>> contextALL = Abstractions.WindowsApi.pInvokes.GetSessionContext();
                    List<string> Users = Abstractions.WindowsApi.pInvokes.GetSessionContextParser(-1, contextALL);
                    List<string> iUsers = Abstractions.WindowsApi.pInvokes.GetInteractiveUserList();
                    foreach (string user in Users)
                    {
                        m_logger.DebugFormat("Program running as user:{0}", user);
                        if (user.Equals(sessionDriver.UserInformation.Username, StringComparison.CurrentCultureIgnoreCase))
                        {
                            //the user is still logged in
                            isLoggedIN = true;
                            if (iUsers.Any(s => s.EndsWith("\\" + sessionDriver.UserInformation.Username, StringComparison.CurrentCultureIgnoreCase)))
                            {
                                int Locked_sessionID = Convert.ToInt32(iUsers.Find(s => s.EndsWith("\\" + sessionDriver.UserInformation.Username, StringComparison.CurrentCultureIgnoreCase)).Split('\\').First());
                                m_logger.DebugFormat("User:{0} is Locked in Session:{1}", sessionDriver.UserInformation.Username, Locked_sessionID);
                                // verify that this unlock is present somewhere in m_sessionPropertyCache
                                // if not, this login is not backed by m_sessionPropertyCache
                                if (m_sessionPropertyCache.GetAll().Any(i => i == Locked_sessionID))
                                {
                                    UserInformation uInfo = m_sessionPropertyCache.Get(Locked_sessionID).First().GetTrackedSingle<UserInformation>();
                                    if (!uInfo.Username.Equals(sessionDriver.UserInformation.Username, StringComparison.CurrentCultureIgnoreCase))
                                    {
                                        // that should never ever happen
                                        m_logger.ErrorFormat("User {0} is Locked in Session {1} but the username doesn't match the session information pGina contains. '{0}' vs. '{2}'", sessionDriver.UserInformation.Username, Locked_sessionID, uInfo.Username);
                                        return new LoginResponseMessage() { Result = false, Message = String.Format("User {0} is Locked in Session {1} but the username doesn't match the session information pGina contains\n\n'{0}' vs '{2}'", sessionDriver.UserInformation.Username, Locked_sessionID, uInfo.Username) };
                                    }
                                }
                                else
                                {
                                    m_logger.ErrorFormat("User {0} is Locked in Session {1} but was not authenticated by pGina. Unable to find SessionProperty in m_sessionPropertyCache.Get({1})", sessionDriver.UserInformation.Username, Locked_sessionID);
                                    return new LoginResponseMessage() { Result = false, Message = String.Format("User {0} is Locked in Session {1} but was not authenticated by pGina\n\nIt is possible that another Credential Provider was used\nor the pGina service has crashed.\n", sessionDriver.UserInformation.Username, Locked_sessionID) };
                                }
                            }
                            else
                            {
                                // verify that this UACed login is present somewhere in m_sessionPropertyCache
                                // if not, this login is not backed by m_sessionPropertyCache
                                foreach (int session in m_sessionPropertyCache.GetAll())
                                {
                                    if (m_sessionPropertyCache.Get(session).Any(s => s.GetTrackedSingle<UserInformation>().Username.Equals(sessionDriver.UserInformation.Username, StringComparison.CurrentCultureIgnoreCase)))
                                    {
                                        m_logger.DebugFormat("User:{0} is pGina UACed in Session:{1}", sessionDriver.UserInformation.Username, session);
                                        isUACLoggedIN = true;
                                        break;
                                    }
                                }
                                // is this user a local user and was not created by pGina
                                /*Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
                                if (Abstractions.WindowsApi.pInvokes.UserGet(sessionDriver.UserInformation.Username, ref userinfo4))
                                {
                                    if (!userinfo4.comment.Contains("pGina created"))
                                    {
                                        m_logger.DebugFormat("User:{0} is local non pGina", sessionDriver.UserInformation.Username);
                                        isUACLoggedIN = true;
                                    }
                                }*/

                                if (!isUACLoggedIN)
                                {
                                    List<string> runas_in_session = new List<string>();
                                    foreach (KeyValuePair<int, List<string>> pair in contextALL)
                                    {
                                        if (pair.Value.Any(s => s.Equals(sessionDriver.UserInformation.Username, StringComparison.CurrentCultureIgnoreCase)))
                                        {
                                            runas_in_session.Add(iUsers.DefaultIfEmpty("").FirstOrDefault(s => s.StartsWith(pair.Key.ToString())));
                                        }
                                    }
                                    m_logger.DebugFormat("There is a program running as {0} but it was'nt started with pGina. I can't log you in because this would conflict with the current running process. Session in which a process is running:{1}", sessionDriver.UserInformation.Username, String.Join(",", runas_in_session));
                                    return new LoginResponseMessage() { Result = false, Message = String.Format("There is a program running as {0} but it was'nt started with pGina.\nI can't log you in because this would conflict with the current running process.\n\nSession in which a process is running:\n{1}", sessionDriver.UserInformation.Username, String.Join("\n", runas_in_session)) };
                                }
                            }
                        }
                    }
                    if (!isLoggedIN)
                    {
                        result = sessionDriver.PerformLoginProcess();
                    }
                    else
                    {
                        // testing. ValidateCredentials would be correct here
                        if (!Abstractions.WindowsApi.pInvokes.ValidateUser(sessionDriver.UserInformation.Username, sessionDriver.UserInformation.Domain, sessionDriver.UserInformation.Password))
                        {
                            m_logger.ErrorFormat("Query local SAM: Bad password");
                            return new LoginResponseMessage()
                            {
                                Result = false,
                                Message = "Bad password",
                                Username = sessionDriver.UserInformation.Username,
                                Domain = sessionDriver.UserInformation.Domain,
                                Password = sessionDriver.UserInformation.Password
                            };
                        }
                    }

                    if (result.Success && (!isLoggedIN || msg.Reason == LoginRequestMessage.LoginReason.CredUI || isUACLoggedIN))
                    {
                        lock (m_sessionPropertyCache)
                        {
                            List<SessionProperties> ses = new List<SessionProperties>();
                            if (m_sessionPropertyCache.Exists(msg.Session))
                            {
                                ses = m_sessionPropertyCache.Get(msg.Session);
                            }
                            bool partof = false;
                            foreach (SessionProperties sess in ses)
                            {
                                UserInformation ui = sess.GetTrackedSingle<UserInformation>();
                                m_logger.InfoFormat("compare stored-user:{0} this-user:{1}", ui.Username, sessionDriver.UserInformation.Username);
                                if (sessionDriver.UserInformation.Username.Equals(ui.Username, StringComparison.CurrentCultureIgnoreCase))
                                {
                                    partof = true;
                                    m_logger.InfoFormat("contain user {0} in sessioninfo:{1} GUID:{2}", ui.Username, msg.Session, sess.Id);
                                    break;
                                }
                            }
                            if (!partof)
                            {
                                if (isLoggedIN)
                                {
                                    UserInformation ui = FindUserInfoInPropertyCache(sessionDriver.UserInformation.Username);
                                    if (ui != null)
                                    {
                                        ui.SessionID = msg.Session;
                                        sessionDriver.SessionProperties.AddTrackedSingle<UserInformation>(ui);
                                    }
                                }
                                else
                                {
                                    // add local profile path
                                    // its not sure that the profile realy ends up there
                                    // a win profile loading error can redirect the path to a temp path too
                                    UserInformation ui = sessionDriver.SessionProperties.GetTrackedSingle<UserInformation>();
                                    if (ui != null)
                                    {
                                        // worst case empty string
                                        ui.LocalProfilePath = Abstractions.Windows.User.GetProfileDir(ui.Username, ui.Password, ui.SID);
                                        sessionDriver.SessionProperties.AddTrackedSingle<UserInformation>(ui);
                                        m_logger.InfoFormat("ses add LocalProfilePath:[{0}]", ui.LocalProfilePath);
                                    }
                                }
                                ses.Add(sessionDriver.SessionProperties);
                                m_logger.InfoFormat("add user {0} to sessioninfo:{1} GUID:{2} CREDUI:{3}", sessionDriver.UserInformation.Username, msg.Session, sessionDriver.SessionProperties.Id, (msg.Reason == LoginRequestMessage.LoginReason.CredUI) ? "true" : "false");
                                m_logger.InfoFormat("ses username:{0} description:{1} credui:{2} isLoggedIN:{3}", ses.Last().GetTrackedSingle<UserInformation>().Username, ses.Last().GetTrackedSingle<UserInformation>().Description, ses.Last().CREDUI, isLoggedIN);
                                m_sessionPropertyCache.Add(msg.Session, ses);
                            }
                        }
                    }
                }
                else
                {
                    // check if username is equal originalusername
                    // if not return originalusername and password
                    bool originalUsernameUnlock = Settings.Get.UseOriginalUsernameInUnlockScenario;
                    if (originalUsernameUnlock && LoginRequestMessage.LoginReason.Unlock == msg.Reason)
                    {
                        m_logger.InfoFormat("Unlock with original Username:{0} for Session:{1}", sessionDriver.UserInformation.Username, msg.Session);
                        lock (m_sessionPropertyCache)
                        {
                            List<SessionProperties> ses = new List<SessionProperties>();
                            if (m_sessionPropertyCache.Exists(msg.Session))
                            {
                                ses = m_sessionPropertyCache.Get(msg.Session);
                            }
                            // the first entry is always the interactive user
                            SessionProperties sess = ses.DefaultIfEmpty(new SessionProperties(Guid.Empty, true)).FirstOrDefault();
                            UserInformation ui = sess.GetTrackedSingle<UserInformation>();
                            if (ui.Username != ui.OriginalUsername)
                            {
                                if (ui.OriginalPassword == sessionDriver.UserInformation.Password)
                                {
                                    sessionDriver.UserInformation.Username = ui.Username;
                                    sessionDriver.UserInformation.Domain = Environment.MachineName;
                                    sessionDriver.UserInformation.Password = ui.Password;
                                    result.Success = true;
                                    m_logger.InfoFormat("Unlock as:{0} for Session:{1}", sessionDriver.UserInformation.Username, msg.Session);
                                }
                                else
                                {
                                    result.Success = false;
                                    result.Message = "Password incorrect!";
                                }
                            }
                        }
                    }
                    else
                    {
                        m_logger.DebugFormat("Parse Request for: {0} in session: {1} reason: {2}", sessionDriver.UserInformation.Username, msg.Session, msg.Reason);
                    }
                }

                if (LastUsernameEnable && msg.Reason == LoginRequestMessage.LoginReason.Login && result.Success)
                {
                    Settings.s_settings.SetSetting("LastUsername", String.Format("{0}", sessionDriver.UserInformation.Username));
                }
                return new LoginResponseMessage()
                {
                    Result = result.Success,
                    Message = result.Message,
                    Username = sessionDriver.UserInformation.Username,
                    Domain = sessionDriver.UserInformation.Domain,
                    Password = sessionDriver.UserInformation.Password
                };
            }
            catch (Exception e)
            {
                m_logger.ErrorFormat("Internal error, unexpected exception while handling login request: {0}", e);
                return new LoginResponseMessage() { Result = false, Message = "Internal error" };
            }
        }
Esempio n. 8
0
        private Boolean SetACL(string dir, string username, string password, uint maxstore, uint retry)
        {
            m_logger.InfoFormat("modify ACE");

            Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
            if (!Abstractions.WindowsApi.pInvokes.UserGet(username, ref userinfo4))
            {
                m_logger.DebugFormat("Can't get userinfo for user {0}", username);
                return false;
            }

            IdentityReference userIref = new SecurityIdentifier(userinfo4.user_sid).Translate(typeof(NTAccount));
            if (!Abstractions.Windows.Security.SetDirOwner(dir, new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).Translate(typeof(NTAccount))))
            {
                m_logger.WarnFormat("Can't set owner for Directory {0}", dir);
                return false;
            }

            if (!Abstractions.Windows.Security.ReplaceDirectorySecurity(dir, new IdentityReference[] { new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null), new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null), userIref }, FileSystemRights.FullControl, AccessControlType.Allow, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None))
            {
                m_logger.WarnFormat("Can't set ACL for Directory {0}", dir);
                return false;
            }

            if (!Abstractions.Windows.Security.RemoveAccRuleFromUnknownUser(dir))
            {
                m_logger.InfoFormat("Can't remove unknown users from {0} ACL", dir);
                //not critical
            }

            if (!SetACLquotaREGfile(dir + "\\NTUSER.DAT", retry, username, maxstore, true, true))
            {
                return false;
            }
            if (File.Exists(dir + @"\AppData\Local\Microsoft\Windows\UsrClass.dat"))
            {
                if (!SetACLquotaREGfile(dir + @"\AppData\Local\Microsoft\Windows\UsrClass.dat", retry, username, maxstore, false, true))
                {
                    return false;
                }
            }

            return true;
        }
Esempio n. 9
0
        private string GetExistingUserProfile(string username, string password, string userSID = "")
        {
            Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
            if (String.IsNullOrEmpty(userSID))
            {
                if (!Abstractions.WindowsApi.pInvokes.UserGet(username, ref userinfo4))
                {
                    m_logger.DebugFormat("Can't get userinfo for user {0}", username);
                    return "";
                }
                try
                {
                    userSID = new SecurityIdentifier(userinfo4.user_sid).Value;
                }
                catch (Exception ex)
                {
                    m_logger.ErrorFormat("failed to convert SID for \"{0}\":{1}", userinfo4.name, ex.ToString());
                    return "";
                }
            }

            m_logger.InfoFormat("SID found:{0}", userSID);
            if (!Abstractions.Windows.User.FixProfileList(userSID))
            {
                m_logger.DebugFormat("Error in FixProfileList {0}", userSID);
            }

            return Abstractions.Windows.User.GetProfileDir(username, password, new SecurityIdentifier(userSID));
        }
Esempio n. 10
0
        private Boolean CreateRoamingFolder(string dir, string username)
        {
            if (!Directory.Exists(dir))
            {
                try
                {
                    Directory.CreateDirectory(dir);
                }
                catch
                {
                    m_logger.WarnFormat("Can't create Directory {0}", dir);
                    return false;
                }
            }

            Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
            if (!Abstractions.WindowsApi.pInvokes.UserGet(username, ref userinfo4))
            {
                m_logger.WarnFormat("Can't get userinfo4 from {0}", username);
                return false;
            }

            IdentityReference userIref = new SecurityIdentifier(userinfo4.user_sid).Translate(typeof(NTAccount));
            if (!Abstractions.Windows.Security.SetDirOwner(dir, new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).Translate(typeof(NTAccount))))
            {
                m_logger.WarnFormat("Can't set owner {0} for Directory {1}", username, dir);
                return false;
            }

            if (!Abstractions.Windows.Security.SetDirectorySecurity(dir, new IdentityReference[] { userIref }, FileSystemRights.Write | FileSystemRights.ReadAndExecute, AccessControlType.Allow, InheritanceFlags.None, PropagationFlags.None))
            {
                m_logger.WarnFormat("Can't set ACL for Directory {0}", dir);
                return false;
            }

            return true;
        }
Esempio n. 11
0
        public Boolean userAdd(Dictionary<string,string> settings, string username, string password, string comment)
        {
            Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();

            //create user
            if (!Abstractions.WindowsApi.pInvokes.UserExists(username))
            {
                if (!Abstractions.WindowsApi.pInvokes.UserADD(username, password, comment))
                {
                    m_logger.DebugFormat("Can't add user {0}", username);
                    return false;
                }
            }

            //get userinfo
            if (!Abstractions.WindowsApi.pInvokes.UserGet(username, ref userinfo4))
            {
                m_logger.DebugFormat("Can't get userinfo for user {0}", username);
                return false;
            }

            //fill userinfo
            userinfo4.profile = null;
            if (!String.IsNullOrEmpty(settings["HomeDir"]))
                userinfo4.home_dir = settings["HomeDir"];
            if (!String.IsNullOrEmpty(settings["HomeDirDrive"]))
                userinfo4.home_dir_drive = settings["HomeDirDrive"];
            if (!String.IsNullOrEmpty(settings["ScriptPath"]))
                userinfo4.script_path = null;
                //userinfo4.script_path = settings["ScriptPath"];
            /*if (Convert.ToInt32(settings["MaxStore"]) > 0)
                userinfo4.max_storage = Convert.ToInt32(settings["MaxStore"]);
            else
                userinfo4.max_storage = -1;*/
            userinfo4.password = password;
            userinfo4.comment = comment;
            userinfo4.flags |= Abstractions.WindowsApi.pInvokes.structenums.UserFlags.UF_NORMAL_ACCOUNT;
            userinfo4.acct_expires = -1;
            userinfo4.logon_hours = IntPtr.Zero;

            //apply userinfo
            if (!Abstractions.WindowsApi.pInvokes.UserMod(username, userinfo4))
            {
                m_logger.DebugFormat("Can't modify user {0}", username);
                return false;
            }
            m_logger.InfoFormat("user {0} created", username);

            return true;
        }
Esempio n. 12
0
        public BooleanResult get(Dictionary<string,string> settings, string username, string password)
        {
            m_logger = LogManager.GetLogger(String.Format("pgSMB2[Roaming:{0}]", username));
            if (!UserCanBeUsed(username))
            {
                // user exists and was not created by pgina
                m_logger.InfoFormat("user {0} does already exist on this system and does not contain a comment of \"pGina created pgSMB2\"", username);
                return new BooleanResult() { Success = true };
            }
            if (!Connect2share(settings["SMBshare"], username, password, Convert.ToUInt32(settings["ConnectRetry"]), false))
            {
                return new BooleanResult() { Success = false, Message = string.Format("Unable to connect to {0}", settings["RoamingSource"]) };
            }
            try
            {
                if (!Directory.Exists(settings["RoamingSource"]))
                {
                    try
                    {
                        Directory.CreateDirectory(settings["RoamingSource"]);
                    }
                    catch (Exception ex)
                    {
                        m_logger.DebugFormat("CreateDirectory({0}) failed {1}", settings["RoamingSource"], ex.Message);
                    }
                }
                string remote_file = settings["RoamingSource"] + "\\" + settings["Filename"];
                if (File.Exists(remote_file) || File.Exists(remote_file + ".bak"))
                {
                    // there is a remote file
                    Boolean loadprofile = true;
                    // what file to use ?
                    if (File.Exists(remote_file))
                    {
                        settings.Add("Filename_real", settings["Filename"]);
                    }
                    else
                    {
                        settings.Add("Filename_real", settings["Filename"] + ".bak");
                        remote_file += ".bak";
                    }

                    // is there a local roaming profile (there shouldnt be any)
                    string ProfDir = GetExistingUserProfile(username, password);
                    // is this a temp profile
                    if (!String.IsNullOrEmpty(ProfDir))
                    {
                        Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
                        if (Abstractions.WindowsApi.pInvokes.UserGet(username, ref userinfo4))
                        {
                            if (userinfo4.comment.EndsWith(" tmp"))
                            {
                                m_logger.InfoFormat("delete temp profile {0}", ProfDir);
                                DirectoryDel(ProfDir, 3);
                            }
                        }
                    }
                    if (File.Exists(ProfDir + "\\ntuser.dat")) //worst case "\\ntuser.dat"
                    {
                        // there is a local profile of this user
                        // we need to compare the write date between the profile and the compressed remote roaming profile
                        // to be sure that we dont overwrite a newer profile with an old one
                        // possibly reason is a BSOD/hard reset ...
                        m_logger.Debug("User " + username + " still own a lokal profile UTCdate:" + File.GetLastWriteTimeUtc(ProfDir + "\\ntuser.dat"));
                        m_logger.Debug("User " + username + " compressed remote profile UTCdate:" + File.GetLastWriteTimeUtc(remote_file));
                        if (DateTime.Compare(File.GetLastWriteTimeUtc(ProfDir + "\\ntuser.dat"), File.GetLastWriteTimeUtc(remote_file)) >= 0)
                        {
                            m_logger.DebugFormat("the local profile ('{0}') is newer/equal than the remote one, im not downloading the remote one", ProfDir);
                            loadprofile = false;
                        }
                        else
                        {
                            m_logger.Debug("the local profile is older than the remote one");
                        }
                    }
                    if (!userAdd(settings, username, password, "pGina created pgSMB2"))
                    {
                        userDel(settings, username, password);
                        return new BooleanResult() { Success = false, Message = string.Format("Unable to add user {0}", username) };
                    }
                    if (loadprofile)
                    {
                        if (!GetProfile(ref settings, username, password))
                        {
                            return new BooleanResult() { Success = false, Message = string.Format("Unable to get the Profile {0} from {1}", settings["Filename"], settings["RoamingSource"]) };
                        }

                        if (!Connect2share(settings["SMBshare"], null, null, 0, true))
                        {
                            m_logger.WarnFormat("unable to disconnect from {0}", settings["RoamingSource"]);
                        }

                        if (!SetACL(settings["UserProfilePath"], username, password, Convert.ToUInt32(settings["MaxStore"]), Convert.ToUInt32(settings["ConnectRetry"])))
                        {
                            userDel(settings, username, password);
                            return new BooleanResult() { Success = false, Message = string.Format("Unable to set ACL for user {0}", username) };
                        }
                    }
                }
                else
                {
                    m_logger.DebugFormat("there is no {0}\\{1} or {2}\\{3}{4}", settings["RoamingSource"], settings["Filename"], settings["RoamingSource"], settings["Filename"], ".bak");

                    if (!userAdd(settings, username, password, "pGina created pgSMB2"))
                    {
                        userDel(settings, username, password);
                        return new BooleanResult() { Success = false, Message = string.Format("Unable to add user {0}", username) };
                    }
                }
            }
            catch (Exception ex)
            {
                return new BooleanResult() { Success = false, Message = string.Format("Unable to get the Roaming Profile from {0}\nError: {1}", settings["RoamingSource"], ex.Message) };
            }
            finally
            {
                if (!Connect2share(settings["SMBshare"], null, null, 0, true))
                {
                    m_logger.WarnFormat("unable to disconnect from {0}", settings["RoamingSource"]);
                }
            }

            return new BooleanResult() { Success = true };
        }
Esempio n. 13
0
        private Boolean UserCanBeUsed(string username)
        {
            Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();

            //get userinfo
            if (!Abstractions.WindowsApi.pInvokes.UserGet(username, ref userinfo4))
            {
                return true;
            }

            //check if this is a pgina user
            if (userinfo4.comment.Contains("pGina created pgSMB2"))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
Esempio n. 14
0
        public BooleanResult get(Dictionary <string, string> settings, string username, string password)
        {
            m_logger = LogManager.GetLogger(String.Format("pgSMB2[Roaming:{0}]", username));
            if (!UserCanBeUsed(username))
            {
                // user exists and was not created by pgina
                m_logger.InfoFormat("user {0} does already exist on this system and does not contain a comment of \"pGina created pgSMB2\"", username);
                return(new BooleanResult()
                {
                    Success = true
                });
            }
            if (!Connect2share(settings["SMBshare"], username, password, Convert.ToUInt32(settings["ConnectRetry"]), false))
            {
                return(new BooleanResult()
                {
                    Success = false, Message = string.Format("Unable to connect to {0}", settings["RoamingSource"])
                });
            }
            try
            {
                if (!Directory.Exists(settings["RoamingSource"]))
                {
                    try
                    {
                        Directory.CreateDirectory(settings["RoamingSource"]);
                    }
                    catch (Exception ex)
                    {
                        m_logger.DebugFormat("CreateDirectory({0}) failed {1}", settings["RoamingSource"], ex.Message);
                    }
                }
                string remote_file = settings["RoamingSource"] + "\\" + settings["Filename"];
                if (File.Exists(remote_file) || File.Exists(remote_file + ".bak"))
                {
                    // there is a remote file
                    Boolean loadprofile = true;
                    // what file to use ?
                    if (File.Exists(remote_file))
                    {
                        settings.Add("Filename_real", settings["Filename"]);
                    }
                    else
                    {
                        settings.Add("Filename_real", settings["Filename"] + ".bak");
                        remote_file += ".bak";
                    }

                    // is there a local roaming profile (there shouldnt be any)
                    string ProfDir = GetExistingUserProfile(username, password);
                    // is this a temp profile
                    if (!String.IsNullOrEmpty(ProfDir))
                    {
                        Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
                        if (Abstractions.WindowsApi.pInvokes.UserGet(username, ref userinfo4))
                        {
                            if (userinfo4.comment.EndsWith(" tmp"))
                            {
                                m_logger.InfoFormat("delete temp profile {0}", ProfDir);
                                DirectoryDel(ProfDir, 3);
                            }
                        }
                    }
                    if (File.Exists(ProfDir + "\\ntuser.dat")) //worst case "\\ntuser.dat"
                    {
                        // there is a local profile of this user
                        // we need to compare the write date between the profile and the compressed remote roaming profile
                        // to be sure that we dont overwrite a newer profile with an old one
                        // possibly reason is a BSOD/hard reset ...
                        m_logger.Debug("User " + username + " still own a lokal profile UTCdate:" + File.GetLastWriteTimeUtc(ProfDir + "\\ntuser.dat"));
                        m_logger.Debug("User " + username + " compressed remote profile UTCdate:" + File.GetLastWriteTimeUtc(remote_file));
                        if (DateTime.Compare(File.GetLastWriteTimeUtc(ProfDir + "\\ntuser.dat"), File.GetLastWriteTimeUtc(remote_file)) >= 0)
                        {
                            m_logger.DebugFormat("the local profile ('{0}') is newer/equal than the remote one, im not downloading the remote one", ProfDir);
                            loadprofile = false;
                        }
                        else
                        {
                            m_logger.Debug("the local profile is older than the remote one");
                        }
                    }
                    if (!userAdd(settings, username, password, "pGina created pgSMB2"))
                    {
                        userDel(settings, username, password);
                        return(new BooleanResult()
                        {
                            Success = false, Message = string.Format("Unable to add user {0}", username)
                        });
                    }
                    if (loadprofile)
                    {
                        if (!GetProfile(ref settings, username, password))
                        {
                            return(new BooleanResult()
                            {
                                Success = false, Message = string.Format("Unable to get the Profile {0} from {1}", settings["Filename"], settings["RoamingSource"])
                            });
                        }

                        if (!Connect2share(settings["SMBshare"], null, null, 0, true))
                        {
                            m_logger.WarnFormat("unable to disconnect from {0}", settings["RoamingSource"]);
                        }

                        if (!SetACL(settings["UserProfilePath"], username, password, Convert.ToUInt32(settings["MaxStore"]), Convert.ToUInt32(settings["ConnectRetry"])))
                        {
                            userDel(settings, username, password);
                            return(new BooleanResult()
                            {
                                Success = false, Message = string.Format("Unable to set ACL for user {0}", username)
                            });
                        }
                    }
                }
                else
                {
                    m_logger.DebugFormat("there is no {0}\\{1} or {2}\\{3}{4}", settings["RoamingSource"], settings["Filename"], settings["RoamingSource"], settings["Filename"], ".bak");

                    if (!userAdd(settings, username, password, "pGina created pgSMB2"))
                    {
                        userDel(settings, username, password);
                        return(new BooleanResult()
                        {
                            Success = false, Message = string.Format("Unable to add user {0}", username)
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                return(new BooleanResult()
                {
                    Success = false, Message = string.Format("Unable to get the Roaming Profile from {0}\nError: {1}", settings["RoamingSource"], ex.Message)
                });
            }
            finally
            {
                if (!Connect2share(settings["SMBshare"], null, null, 0, true))
                {
                    m_logger.WarnFormat("unable to disconnect from {0}", settings["RoamingSource"]);
                }
            }


            return(new BooleanResult()
            {
                Success = true
            });
        }
Esempio n. 15
0
        public BooleanResult AuthenticatedUserGateway(SessionProperties properties)
        {
            // Our job, if we've been elected to do gateway, is to ensure that an
            //  authenticated user:
            //
            //  1. Has a local account
            //  2. That account's password is set to the one they used to authenticate
            //  3. That account is a member of all groups listed, and not a member of any others

            // Is failure at #3 a total fail?
            bool failIfGroupSyncFails = Settings.Store.GroupCreateFailIsFail;

            // Groups everyone is added to
            string[] MandatoryGroups = Settings.Store.MandatoryGroups;

            // user info
            UserInformation userInfo = properties.GetTrackedSingle<UserInformation>();

            // is this a pgina user?
            Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
            if (Abstractions.WindowsApi.pInvokes.UserGet(userInfo.Username, ref userinfo4)) //true if user exists
            {
                if (!userinfo4.comment.Contains("pGina created"))
                {
                    m_logger.InfoFormat("User {0} is'nt a pGina created user. I'm not executing Gateway stage", userInfo.Username);
                    return new BooleanResult() { Success = true };
                }
            }

            // Add user to all mandatory groups
            if (MandatoryGroups.Length > 0)
            {
                foreach (string group in MandatoryGroups)
                {
                    string group_string=group;

                    m_logger.DebugFormat("Is there a Group with SID/Name:{0}", group);
                    using (GroupPrincipal groupconf = LocalAccount.GetGroupPrincipal(group))
                    {
                        if (groupconf != null)
                        {
                            m_logger.DebugFormat("Groupname: \"{0}\"", groupconf.Name);
                            group_string = groupconf.Name;
                        }
                        else
                        {
                            m_logger.ErrorFormat("Group: \"{0}\" not found", group);
                            m_logger.Error("Failsave add user to group Users");
                            using (GroupPrincipal groupfail = LocalAccount.GetGroupPrincipal(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null).ToString()))
                            {
                                if (groupfail != null)
                                {
                                    group_string = groupfail.Name;
                                }
                                else
                                {
                                    m_logger.Debug("no BuiltinUsers. I'm out of options");
                                    group_string = null;
                                }
                            }
                        }
                    }

                    if (group_string != null)
                        userInfo.AddGroup(new GroupInformation() { Name = group_string });
                }
            }

            try
            {
                m_logger.DebugFormat("AuthenticatedUserGateway({0}) for user: {1}", properties.Id.ToString(), userInfo.Username);
                LocalAccount.SyncUserInfoToLocalUser(userInfo);
                using (UserPrincipal user = LocalAccount.GetUserPrincipal(userInfo.Username))
                {
                    userInfo.SID = user.Sid;
                    userInfo.Description = user.Description;
                }
                properties.AddTrackedSingle<UserInformation>(userInfo);
            }
            catch (LocalAccount.GroupSyncException e)
            {
                if (failIfGroupSyncFails)
                    return new BooleanResult() { Success = false, Message = string.Format("Unable to sync users local group membership: {0}", e.RootException) };
            }
            catch(Exception e)
            {
                return new BooleanResult() { Success = false, Message = string.Format("Unexpected error while syncing user's info: {0}", e) };
            }

            return new BooleanResult() { Success = true };
        }