public PluginDriver() { m_logger = LogManager.GetLogger(string.Format("PluginDriver:{0}", m_sessionId)); m_properties = new SessionProperties(m_sessionId); // Add the user information object we'll be using for this session UserInformation userInfo = new UserInformation(); m_properties.AddTrackedSingle<UserInformation>(userInfo); // Add the plugin tracking object we'll be using for this session PluginActivityInformation pluginInfo = new PluginActivityInformation(); pluginInfo.LoadedAuthenticationGatewayPlugins = PluginLoader.GetOrderedPluginsOfType<IPluginAuthenticationGateway>(); pluginInfo.LoadedAuthenticationPlugins = PluginLoader.GetOrderedPluginsOfType<IPluginAuthentication>(); pluginInfo.LoadedAuthorizationPlugins = PluginLoader.GetOrderedPluginsOfType<IPluginAuthorization>(); m_properties.AddTrackedSingle<PluginActivityInformation>(pluginInfo); m_logger.DebugFormat("New PluginDriver created"); }
static void Main(string[] args) { SessionProperties properties = new SessionProperties(new Guid("12345678-1234-1234-1234-123412341234")); UserInformation userInfo = new UserInformation(); userInfo.Username = "******"; userInfo.Email = "*****@*****.**"; userInfo.Fullname = "Gandalf The Gray"; userInfo.LoginScript = "net use x: \\lserver\bakasracky"; userInfo.Password = "******"; properties.AddTrackedSingle<UserInformation>(userInfo); PluginImpl plugin = new PluginImpl(); var authResult = plugin.AuthenticateUser(properties); Debug.Assert(authResult.Success == true, "auth should succeed!"); var gatewayResult = plugin.AuthenticatedUserGateway(properties); Debug.Assert(authResult.Success == true, "gateway should succeed!"); System.Console.Write("DONE"); }
public void InitTest() { // Default test settings, reset for each test Settings.Store.LdapHost = host; Settings.Store.LdapPort = port; Settings.Store.LdapTimeout = 10; Settings.Store.EncryptionMethod = (int)encMethod; Settings.Store.RequireCert = validateCert; Settings.Store.SearchDN = searchDN; Settings.Store.SetEncryptedSetting("SearchPW", searchPW); Settings.Store.GroupDnPattern = "cn=%g,ou=Group,dc=example,dc=com"; Settings.Store.GroupMemberAttrib = "memberUid"; Settings.Store.UseAuthBindForAuthzAndGateway = false; // Authentication Settings.Store.AllowEmptyPasswords = false; Settings.Store.DnPattern = "uid=%u,ou=People,dc=example,dc=com"; Settings.Store.DoSearch = false; Settings.Store.SearchFilter = ""; Settings.Store.SearchContexts = new string[] { }; // Authorization Settings.Store.GroupAuthzRules = new string[] { (new GroupAuthzRule(true)).ToRegString() }; Settings.Store.AuthzRequireAuth = false; Settings.Store.AuthzAllowOnError = true; // Gateway Settings.Store.GroupGatewayRules = new string[] { }; // Set up session props m_props = new SessionProperties(BogusSessionId); UserInformation userInfo = new UserInformation(); m_props.AddTrackedSingle<UserInformation>(userInfo); userInfo.Username = "******"; userInfo.Password = "******"; PluginActivityInformation actInfo = new PluginActivityInformation(); m_props.AddTrackedSingle<PluginActivityInformation>(actInfo); }
internal bool Run(int sessionId, string cmd, UserInformation userInfo, bool pwd, bool sys) { string expand_cmd = ""; foreach (string c in cmd.Split(' ')) { string ce = c; if (!Regex.IsMatch(c, @"(?i)%\S+%") && Regex.IsMatch(c, @"(?i)%\S+")) { ce = ce.Replace("%u", userInfo.Username); ce = ce.Replace("%o", userInfo.OriginalUsername); if (pwd) { ce = ce.Replace("%p", userInfo.Password); ce = ce.Replace("%b", userInfo.oldPassword); } ce = ce.Replace("%s", userInfo.SID.Value); ce = ce.Replace("%e", userInfo.PasswordEXP.ToString()); ce = ce.Replace("%i", userInfo.SessionID.ToString()); expand_cmd += ce + " "; } else { expand_cmd += c + " "; } } expand_cmd = expand_cmd.Trim(); m_logger.InfoFormat("execute {0}", expand_cmd); if (sys) return Abstractions.WindowsApi.pInvokes.StartProcessInSessionWait(sessionId, expand_cmd); else return Abstractions.WindowsApi.pInvokes.StartUserProcessInSessionWait(sessionId, expand_cmd); }
internal Dictionary<string, Dictionary<bool, string>> GetSettings(UserInformation userInfo) { Dictionary<string, Dictionary<bool, string>> ret = new Dictionary<string, Dictionary<bool, string>>(); Dictionary<bool, string> lines = new Dictionary<bool, string>(); if (ParseSettings((string[])Settings.Store.authe_sys, ref lines)) ret.Add("authe_sys", lines); if (!String.IsNullOrEmpty(userInfo.script_authe_sys)) if (ParseSettings((string[])Settings.Store.authe_sys, ref lines)) ret.Add("authe_sys", lines); if (ParseSettings((string[])Settings.Store.autho_sys, ref lines)) ret.Add("autho_sys", lines); if (!String.IsNullOrEmpty(userInfo.script_autho_sys)) if (ParseSettings((string[])Settings.Store.autho_sys, ref lines)) ret.Add("autho_sys", lines); if (ParseSettings((string[])Settings.Store.gateway_sys, ref lines)) ret.Add("gateway_sys", lines); if (!String.IsNullOrEmpty(userInfo.script_gateway_sys)) if (ParseSettings((string[])Settings.Store.gateway_sys, ref lines)) ret.Add("gateway_sys", lines); if (ParseSettings((string[])Settings.Store.notification_sys, ref lines)) ret.Add("notification_sys", lines); if (!String.IsNullOrEmpty(userInfo.script_notification_sys)) if (ParseSettings((string[])Settings.Store.notification_sys, ref lines)) ret.Add("notification_sys", lines); if (ParseSettings((string[])Settings.Store.notification_usr, ref lines)) ret.Add("notification_usr", lines); if (!String.IsNullOrEmpty(userInfo.script_notification_usr)) if (ParseSettings((string[])Settings.Store.notification_usr, ref lines)) ret.Add("notification_usr", lines); if (ParseSettings((string[])Settings.Store.changepwd_sys, ref lines)) ret.Add("changepwd_sys", lines); if (!String.IsNullOrEmpty(userInfo.script_changepwd_sys)) if (ParseSettings((string[])Settings.Store.changepwd_sys, ref lines)) ret.Add("changepwd_sys", lines); if (ParseSettings((string[])Settings.Store.changepwd_usr, ref lines)) ret.Add("changepwd_usr", lines); if (!String.IsNullOrEmpty(userInfo.script_changepwd_usr)) if (ParseSettings((string[])Settings.Store.changepwd_usr, ref lines)) ret.Add("changepwd_usr", lines); return ret; }
public LocalAccount(UserInformation userInfo) { UserInfo = userInfo; }
// Load userInfo.Username's group list and populate userInfo.Groups accordingly public static void SyncLocalGroupsToUserInfo(UserInformation userInfo) { ILog logger = LogManager.GetLogger("LocalAccount.SyncLocalGroupsToUserInfo"); try { SecurityIdentifier EveryoneSid = new SecurityIdentifier("S-1-1-0"); SecurityIdentifier AuthenticatedUsersSid = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null); if (LocalAccount.UserExists(userInfo.Username)) { using (UserPrincipal user = LocalAccount.GetUserPrincipal(userInfo.Username)) { foreach (GroupPrincipal group in LocalAccount.GetGroups(user)) { // Skip "Authenticated Users" and "Everyone" as these are generated if (group.Sid == EveryoneSid || group.Sid == AuthenticatedUsersSid) continue; userInfo.AddGroup(new GroupInformation() { Name = group.Name, Description = group.Description, SID = group.Sid }); } } } } catch(Exception e) { logger.ErrorFormat("Unexpected error while syncing local groups, skipping rest: {0}", e); } }
public static void SyncUserInfoToLocalUser(UserInformation userInfo) { LocalAccount la = new LocalAccount(userInfo); la.SyncToLocalUser(); }
private void SyncUserPrincipalInfo(UserPrincipal user, UserInformation info) { using(DirectoryEntry userDe = m_sam.Children.Find(info.Username, "User")) { if(!string.IsNullOrEmpty(info.Description)) userDe.Properties["Description"].Value = info.Description; if(!string.IsNullOrEmpty(info.Fullname)) userDe.Properties["FullName"].Value = info.Fullname; userDe.Invoke("SetPassword", new object[] { info.Password }); userDe.CommitChanges(); } }
private UserPrincipal CreateOrGetUserPrincipal(UserInformation userInfo) { UserPrincipal user = null; if ( ! LocalAccount.UserExists(userInfo.Username) ) { // See note about MS bug in CreateOrGetGroupPrincipal to understand the mix of DE/Principal here: using (user = new UserPrincipal(m_machinePrincipal)) { user.Name = userInfo.Username; user.SetPassword(userInfo.Password); user.Save(); // Sync via DE SyncUserPrincipalInfo(user, userInfo); // We have to re-fetch to get changes made via underlying DE return GetUserPrincipal(user.Name); } } user = GetUserPrincipal(userInfo.Username); if (user != null) return user; else throw new Exception( String.Format("Unable to get user principal for account that apparently exists: {0}", userInfo.Username)); }
private void cleanup(UserInformation userInfo, int sessionID, SessionProperties properties) { bool scramble = Settings.Store.ScramblePasswords; bool remove = Settings.Store.RemoveProfiles; while (true) { // logoff detection is quite a problem under NT6 // a disconnectEvent is only triggered during a logoff // but not during a shutdown/reboot // and the SessionLogoffEvent is only saying that the user is logging of // So, there is no event that is fired during a user-logoff/reboot/shutdown // that indicates that the user has logged of if (Abstractions.WindowsApi.pInvokes.IsSessionLoggedOFF(sessionID) || IsShuttingDown) { break; } else { Thread.Sleep(1000); } } while (true) { // if no other notification plugin is working on this user // if the first entry from GetNotificationPlugins is equal to this plugin UID IEnumerable<Guid> guids = properties.GetTrackedSingle<PluginActivityInformation>().GetNotificationPlugins(); /*foreach(Guid gui in guids) { m_logger.DebugFormat("{1} PluginActivityInformation guid:{0}", gui, userInfo.Username); }*/ if (guids.DefaultIfEmpty(Guid.Empty).FirstOrDefault().Equals(PluginUuid) || guids.ToList().Count == 0) { break; } Thread.Sleep(1000); } m_logger.DebugFormat("{0} start cleanup with Description \"{1}\"", userInfo.Username, userInfo.Description); if (LocalAccount.UserExists(userInfo.Username)) { lock (logoff_locker) { LocalAccount lo = new LocalAccount(userInfo); if (remove) { m_logger.DebugFormat("{0} remove profile", userInfo.Username); lo.RemoveUserAndProfile(userInfo.Username, sessionID); } else { m_logger.DebugFormat("{0} not removing profile", userInfo.Username); } if (scramble && !remove) { m_logger.DebugFormat("{0} scramble password", userInfo.Username); lo.ScrambleUsersPassword(userInfo.Username); } else { m_logger.DebugFormat("{0} not scramble password", userInfo.Username); } m_logger.DebugFormat("{0} cleanup done", userInfo.Username); } } else { m_logger.DebugFormat("{0} doesnt exist", userInfo.Username); } try { Locker.TryEnterWriteLock(-1); RunningTasks.Remove(userInfo.Username.ToLower()); PluginActivityInformation notification = properties.GetTrackedSingle<PluginActivityInformation>(); notification.DelNotificationResult(PluginUuid); m_logger.InfoFormat("{1} PluginActivityInformation del Guid:{0}", PluginUuid, userInfo.Username); properties.AddTrackedSingle<PluginActivityInformation>(notification); foreach (Guid guid in properties.GetTrackedSingle<PluginActivityInformation>().GetNotificationPlugins()) { m_logger.InfoFormat("{1} PluginActivityInformation Guid:{0}", guid, userInfo.Username); } } finally { Locker.ExitWriteLock(); } }
private Dictionary<string, string> GetSettings(string username, UserInformation userInfo) { Dictionary<string,string> settings = new Dictionary<string,string>(); Abstractions.WindowsApi.pInvokes.structenums.OSVERSIONINFOW verinfo = Abstractions.WindowsApi.pInvokes.VersionsInfo(); if (verinfo.dwMajorVersion == 0) { m_logger.WarnFormat("GetSettings: VersionsInfo() failed. I'm unable to detect OS beyond Windows 8.0"); verinfo.dwBuildNumber = Environment.OSVersion.Version.Build; verinfo.dwMajorVersion = Environment.OSVersion.Version.Major; verinfo.dwMinorVersion = Environment.OSVersion.Version.Minor; verinfo.dwPlatformId = Environment.OSVersion.Version.Build; } Dictionary<string,string> global_settings = pGina.Shared.Settings.pGinaDynamicSettings.GetSettings(pGina.Shared.Settings.pGinaDynamicSettings.pGinaRoot, new string[] { "" }); string[,] array = new string[,] { {"TempComp", Settings.Store.TempComp.ToString()}, {"Filename", (!String.IsNullOrEmpty(userInfo.pgSMB_Filename)) ? userInfo.pgSMB_Filename : Settings.Store.Filename.ToString()}, {"SMBshare", (!String.IsNullOrEmpty(userInfo.pgSMB_SMBshare)) ? userInfo.pgSMB_SMBshare : Settings.Store.SMBshare.ToString()}, {"RoamingSource", (!String.IsNullOrEmpty(userInfo.usri4_profile)) ? userInfo.usri4_profile : Settings.Store.RoamingSource.ToString()}, {"ConnectRetry", Settings.Store.ConnectRetry.ToString()}, {"Compressor", Settings.Store.Compressor.ToString()}, {"UncompressCLI", Settings.Store.UncompressCLI.ToString()}, {"CompressCLI", Settings.Store.CompressCLI.ToString()}, {"MaxStore", (userInfo.usri4_max_storage > 0) ? userInfo.usri4_max_storage.ToString() : Settings.Store.MaxStore.ToString()}, {"ntp", (global_settings.ContainsKey("ntpservers")? global_settings["ntpservers"].Replace('\0',' ') : "")}, /*maybe emty*/ {"MaxStoreExclude", Settings.StoreGlobal.MaxStoreExclude.ToString()}, {"HomeDir", (!String.IsNullOrEmpty(userInfo.usri4_home_dir)) ? userInfo.usri4_home_dir : Settings.Store.HomeDir.ToString()}, {"HomeDirDrive", (!String.IsNullOrEmpty(userInfo.usri4_home_dir_drive)) ? userInfo.usri4_home_dir_drive : Settings.Store.HomeDirDrive.ToString()}, {"ScriptPath", (!String.IsNullOrEmpty(userInfo.LoginScript)) ? userInfo.LoginScript : Settings.Store.ScriptPath.ToString()}, }; for (uint x = 0; x <= array.GetUpperBound(0); x++ ) { array[x, 1] = Environment.ExpandEnvironmentVariables(array[x, 1]).Replace("%u", username); if (x > 2) { // mask the filename in the string to prevent a replacement array[x, 1] = array[x, 1].Replace(array[2, 1],"??????????"); // replace the roaming folder (NT6 adds .V2) array[x, 1] = array[x, 1].Replace(array[0, 1], array[1, 1]); // unmask the filename array[x, 1] = array[x, 1].Replace("??????????", array[2, 1]); } if (x < 11) // first 11 fields shouldnt be empty { if (String.IsNullOrEmpty(array[x, 1])) { settings.Add("ERROR", array[x, 0]); } } settings.Add(array[x, 0], array[x, 1]); } List<string> keys = new List<string>(settings.Keys); for (uint y = 1; y <= 4; y++) { foreach (string key in keys) { settings[key] = settings[key].Replace("%f", settings["Filename"]); settings[key] = settings[key].Replace("%s", settings["SMBshare"]); settings[key] = settings[key].Replace("%r", settings["RoamingSource"]); settings[key] = settings[key].Replace("%d", settings["TempComp"]); } } foreach (KeyValuePair<string, string> pair in settings) { m_logger.DebugFormat("GetSettings:\"{0}\" \"{1}\"",pair.Key,pair.Value); } return settings; }
private void cleanup(UserInformation userInfo, int sessionID, SessionProperties properties) { Dictionary<string, string> settings = GetSettings(userInfo.Username, userInfo); try { while (true) { // logoff detection is quite a problem under NT6 // a disconnectEvent is only triggered during a logoff // but not during a shutdown/reboot // and the SessionLogoffEvent is only saying that the user is logging of // So, there is no event that is fired during a user-logoff/reboot/shutdown // that indicates that the user has logged of if (Abstractions.WindowsApi.pInvokes.IsSessionLoggedOFF(sessionID) || IsShuttingDown) { break; } else { Thread.Sleep(1000); } } while (true) { // if no other notification plugin is working on this user // if the first entry from GetNotificationPlugins is equal to this plugin UID IEnumerable<Guid> guids = properties.GetTrackedSingle<PluginActivityInformation>().GetNotificationPlugins(); /*foreach(Guid gui in guids) { m_logger.DebugFormat("{1} PluginActivityInformation guid:{0}", gui, userInfo.Username); }*/ if (guids.DefaultIfEmpty(Guid.Empty).FirstOrDefault().Equals(PluginUuid) || guids.ToList().Count == 0) { break; } Thread.Sleep(1000); } Roaming ro = new Roaming(); if (!userInfo.Description.EndsWith(" tmp")) //its a tmp profile do not upload { BooleanResult RetBool = ro.put(settings, userInfo.Username, userInfo.Password, userInfo.LocalProfilePath, userInfo.SID); if (!RetBool.Success) { m_logger.ErrorFormat("unable to Logoff {0} Error:{1}", userInfo.Username, RetBool.Message); Abstractions.Windows.Networking.sendMail(pGina.Shared.Settings.pGinaDynamicSettings.GetSettings(pGina.Shared.Settings.pGinaDynamicSettings.pGinaRoot, new string[] { "notify_pass" }), userInfo.Username, userInfo.Password, String.Format("pGina: unable to Logoff {0} from {1}", userInfo.Username, Environment.MachineName), RetBool.Message); } } m_logger.InfoFormat("{0} cleanup done", userInfo.Username); } catch (Exception ex) { m_logger.FatalFormat("{0} Error during Logoff of {1}", userInfo.Username, ex.Message); Abstractions.Windows.Networking.sendMail(pGina.Shared.Settings.pGinaDynamicSettings.GetSettings(pGina.Shared.Settings.pGinaDynamicSettings.pGinaRoot, new string[] { "notify_pass" }), userInfo.Username, userInfo.Password, String.Format("pGina: Logoff Exception {0} from {1}", userInfo.Username, Environment.MachineName), "Logoff Exception\n" + ex.Message); } try { Locker.TryEnterWriteLock(-1); RunningTasks.Remove(userInfo.Username.ToLower()); PluginActivityInformation notification = properties.GetTrackedSingle<PluginActivityInformation>(); notification.DelNotificationResult(PluginUuid); m_logger.InfoFormat("{1} PluginActivityInformation del Guid:{0}", PluginUuid, userInfo.Username); properties.AddTrackedSingle<PluginActivityInformation>(notification); foreach (Guid guid in properties.GetTrackedSingle<PluginActivityInformation>().GetNotificationPlugins()) { m_logger.InfoFormat("{1} PluginActivityInformation Guid:{0}", guid, userInfo.Username); } } finally { Locker.ExitWriteLock(); } }
private void SyncUserPrincipalInfo(UserInformation info) { using(DirectoryEntry userDe = m_sam.Children.Find(info.Username, "User")) { if (!string.IsNullOrEmpty(info.Description)) userDe.Properties["Description"].Value = info.Description; if (!string.IsNullOrEmpty(info.Fullname)) userDe.Properties["FullName"].Value = info.Fullname; if (!string.IsNullOrEmpty(info.usri4_home_dir)) userDe.Properties["HomeDirectory"].Value = info.usri4_home_dir.Replace("%u", info.Username); if (!string.IsNullOrEmpty(info.usri4_home_dir_drive)) userDe.Properties["HomeDirDrive"].Value = info.usri4_home_dir_drive; if (!info.Description.Contains("pgSMB")) if (!string.IsNullOrEmpty(info.usri4_profile)) userDe.Properties["Profile"].Value = info.usri4_profile; userDe.Invoke("SetPassword", new object[] { info.Password }); userDe.Properties["PasswordExpired"].Value = Convert.ToInt32(info.PasswordEXP); userDe.CommitChanges(); } }
private UserPrincipal CreateOrGetUserPrincipal(UserInformation userInfo) { UserPrincipal user = null; if ( ! LocalAccount.UserExists(userInfo.Username) ) { // See note about MS bug in CreateOrGetGroupPrincipal to understand the mix of DE/Principal here: using (user = new UserPrincipal(m_machinePrincipal)) { user.Name = userInfo.Username; user.SetPassword(userInfo.Password); user.Description = "pGina created"; userInfo.Description = user.Description; if (userInfo.PasswordEXP) user.ExpirePasswordNow(); user.Save(); // Sync via DE SyncUserPrincipalInfo(userInfo); // We have to re-fetch to get changes made via underlying DE return GetUserPrincipal(user.Name); } } user = GetUserPrincipal(userInfo.Username); if (user == null) m_logger.ErrorFormat("Unable to get user principal for account that apparently exists: {0}", userInfo.Username); return user; }
private static Boolean SetACL(UserInformation userInfo, string ProfileExtension) { if (!Abstractions.WindowsApi.pInvokes.RegistryLoad(Abstractions.WindowsApi.pInvokes.structenums.RegistryLocation.HKEY_LOCAL_MACHINE, userInfo.Username, userInfo.usri4_profile + ProfileExtension/*.V2|.V5*/ + "\\NTUSER.DAT")) { m_logger.WarnFormat("Can't load regfile {0}", userInfo.usri4_profile + ProfileExtension/*.V2|.V5*/ + "\\NTUSER.DAT"); return false; } if (!Abstractions.Windows.Security.RegSec(Abstractions.WindowsApi.pInvokes.structenums.RegistryLocation.HKEY_LOCAL_MACHINE, userInfo.Username, userInfo.Username)) { m_logger.WarnFormat("Can't set ACL for regkey {0}\\{1}", Abstractions.WindowsApi.pInvokes.structenums.RegistryLocation.HKEY_LOCAL_MACHINE.ToString(), userInfo.Username); return false; } if (!Abstractions.WindowsApi.pInvokes.RegistryUnLoad(Abstractions.WindowsApi.pInvokes.structenums.RegistryLocation.HKEY_LOCAL_MACHINE, userInfo.Username)) { m_logger.WarnFormat("Can't unload regkey {0}\\{1}", userInfo.usri4_profile + ProfileExtension/*.V2|.V5*/, "NTUSER.DAT"); return false; } return true; }