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))); }
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); }
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); }
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); } }
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); }
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 }); }
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" }; } }
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; }
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)); }
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; }
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; }
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 }; }
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; } }
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 }); }
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 }; }