My goal is to create a system that can create an endless amount of accounts and store them in a list, the system will then check this list to see if the account exists and if it does it well let the user login. Ultimately I want to create a method which can create accounts however for now I am sticking with 2. The way I expect my code to function is that it creates 2 separate accounts, each with its own object properties, and then let the user login with either account. What ends up happening is both accounts appear in the list however the 2nd account seems to overwrite all the properties of the first. I'm still new to c# and I'm not quite sure what caused this to happen/how I can fix it.
I have tried to separate the initialization of the 2 accounts however I'm not sure I've done it correctly or if that is even the right term.
The Main section of my code starts by creating a list, and then creating those accounts within the list using predetermined functions, It then prints out the account details so that they can clearly be seen.
static void Main(string[] args)
{
//This List is used to store Accounts
AccountInteractions accountInteractions = new AccountInteractions();
//First Account
Account account = new Account();
account.ReadAccount();
accountInteractions.AddAccount(account);
Console.WriteLine();
//Second Account
account = new Account();
account.ReadAccount();
accountInteractions.AddAccount(account);
//Listing accounts and account variables
foreach (var item in accountInteractions.AccountList)
{
Console.WriteLine("Name: {0}, Email: {1}, Password: ${2}", account.Username, account.UserEmail, account.UserPassword);
}
}
The methods below show how the users input is used to create the accounts, also shown is how the system checks for whether the account matches that within the list.
public void ReadAccount()
{
Console.Write("Username: ");
Username = Console.ReadLine();
Console.Write("Email: ");
UserEmail = Console.ReadLine();
Console.Write("Password: ");
UserPassword = Console.ReadLine();
Login = false;
}
public void LogInToAccount(Account account)
{
//Setup User Input
Console.WriteLine();
Console.Write("Email: ");
userEmailCheck = Console.ReadLine();
Console.Write("Password: ");
userPasswordCheck = Console.ReadLine();
//Verifying Details to check if account exists
if (account.userEmailCheck == account.UserEmail & account.userPasswordCheck == account.UserPassword)
{
account.Login = true;
Console.WriteLine("Login Successful");
}
else
{
Console.WriteLine("Invalid credentials, please try again.");
account.LogInToAccount(account);
}
}
This picture shows the output using basic details entered
As can be seen despite entering separate details both accounts end up having the same properties. Ultimately both accounts should be able to login using the LogInToAccount() method, and both should have their own unique properties.
You are using the wrong variable account instead of the loop variable item here:
foreach (var item in accountInteractions.AccountList)
{
Console.WriteLine("Name: {0}, Email: {1}, Password: ${2}", account.Username, account.UserEmail, account.UserPassword);
}
account refers to the last initialized account. The reason for such problems is that you do too much in the same scope. Use methods, for example one to output existing accounts.
Related
I need to create an installer for my operating system in Cosmos kernel but I don't know where to start or how to create it.
[See my Operating system]
https://www.mediafire.com/file/3nr6pbjfg7p1gfq/GoPixelOS.iso/file
I want to install the OS on the machine, how do I do that?
I think I can help you. but it actually makes a new user. but it still needs installation. but this won't work for another computer that does not have Filesystem.vmdk. maybe it is just a virtual file system
First you will need a file system
you will also need System.io
on before writing this codeā¬
if (!File.Exists("0:\\youros\\System.txt")) //you will need Using.System.io and ! mean not equal
{
Console.Clear();
Console.WriteLine("YourOS will be install in your pc");
Console.WriteLine("Create a username and password:");
Console.Write("Username: ");
string username = Console.ReadLine();
Console.Write("Password: ");
string cPassword = Console.ReadLine();
Console.Write(username +"> "); //when your put username variable it should look like this "The user name: "
Console.WriteLine("Creating System Directory..."); //Creating Directory or folder
fs.CreateDirectory("0:\\yourOS\\");
Console.WriteLine("Creating File for user");
fs.CreateFile("0:\\yourOS\\System.txt"); //Creating File System
fs.CreateFile("0:\\yourOS\\users.db");
fs.CreateFile("0:\\yourOS\\password.db"); //creating a password files
Console.WriteLine("Setting User Preferences...");
File.WriteAllText("0:\\yourOS\\System.txt", write);
File.WriteAllText("0:\\yourOS\\users.db", username); ` //This will save username
File.WriteAllText("0:\\yourOS\\password.db", cPassword); //this one will save the user password
Console.WriteLine("Reboot ONEOS in 3 seconds");
Cosmos.HAL.Global.PIT.Wait(3000);
Sys.Power.Reboot(); //when the installation done it will reboot`
else //after reboot it will go to else and just leave it blank. it will just go to run() after the else
{
password = File.ReadAllText("0:\\oneos\\password.db"); //this will show the
Console.Write("Type your password: ")
var type Console.ReadLine();
if (type == password)
{
//just leave it blank. it will go to protected override void run()
}
else
}
Sys.Power.Reboot(); //this will reboot the OS if user type wrong password
{
}
That is for the installation but if you want the installation to be more useful you will need this
//protected override void Run()
text = File.ReadAllText("0:\\oneos\\users.db"); //this will show the username
Console.Write(text + "> ");
var input = Console.ReadLine();
And that is if you want to make it show error put try and catch to your OS if there has an error.
if you can understand this you can make the os have user selection like windows logon screen.
If there is a problem please tell me
I'm trying to search for users in AD and display them in a list box only when they are inactive.
This is the code I have written
private void button1_Click(object sender, EventArgs e)
{
PrincipalContext insPrincipalContext = new PrincipalContext(ContextType.Domain, "DX", "DC=RX,DC=PX,DC=com");
ListUser(insPrincipalContext);
}
private void ListUser(PrincipalContext insPrincipalContext)
{
UserPrincipal insUserPrincipal = new UserPrincipal(insPrincipalContext);
insUserPrincipal.Name = "*";
SearchUsers(insUserPrincipal);
}
private void SearchUsers(UserPrincipal parUserPrincipal)
{
listBox1.Items.Clear();
PrincipalSearcher insPrincipalSearcher = new PrincipalSearcher();
insPrincipalSearcher.QueryFilter = parUserPrincipal;
PrincipalSearchResult<Principal> results = insPrincipalSearcher.FindAll();
foreach (Principal p in results)
{
UserPrincipal theUser = p as UserPrincipal;
if (theUser != null)
{
if (***theUser.IsAccountLockedOut()***)//**Is this same as Active or Inactive?**
{
listBox1.Items.Add(p);
}
else
{
}
}
}
}
So my question is whether (theUser.)IsAccountLockedUp is same as asking if the user is inactive?
I know one might suggest that this question is a copy of Get members of Active Directory Group and check if they are enabled or disabled but the problem here is I don't have test users to test on and I'm just starting with C#.
Thank You
IsAccountLockedOut corresponds to "Account is locked out" in the Active Directory account properties. This means that account was locked due to too many bad password attempts.
There is another setting in the properties "Account is disabled". This is often used by Administrators (of Identity Management Systems in large enterprise environments) to disable a account if the corresponding person left the company. So the account cannot be used anymore, but it is still there and works for SID lookup (will be displayed as name in groups or ACLs).
Ask yourself what your intention is. What do mean by "inactive" ?
You can probably use this as a starting point:
if (theUser != null)
{
if (theUser.IsAccountLockedOut())
{
// account locked out
}
// Enabled is nullable bool
if (!(theUser.Enabled == true))
{
// account disabled
}
if (theUser.LastLogon == null ||
theUser.LastLogon < DateTime.Now - TimeSpan.FromDays(150))
{
// never logged on or last logged on long time ago
// see below in the text for important notes !
}
}
Checking for LastLogon can be useful to find orphaned accounts. But be aware that a women may be in maternity leave :-)
Important
In Active Directory, there are two similar attributes:
LastLogon
LastLogonTimeStamp
See
http://blogs.technet.com/b/askds/archive/2009/04/15/the-lastlogontimestamp-attribute-what-it-was-designed-for-and-how-it-works.aspx
for the difference. Short: only the LastLogonTimeStamp attribute is replicated between domain controllers and can be safely used for checking orphaned accounts. But even LastLogonTimeStamp is not really accurate, but is sufficient for detecting "old" / unused accounts.
I have not yet checked to which of them UserPrinciple.LastLogon corresponds. Be careful.
I am in the process of writing an own library for searching in the AD, which is based on the System.DirectoryServices classes. This has some benefits: better control and better performance. If it is ready, I will probably make it public.
Firstly, I am new to AD / LDAP etc so this might be something obvious (I do hope so?!) and apologise if my terminology is not right, please correct me.
We have two domains, BUSINESS (being a Global Group) and AUTH (being a Domain Local Group) with one way trust between them (AUTH trusts BUSINESS).
The following code works on MachineA sitting on BUSINESS domain when string LDAPServer = "BUSINESS".
But when run on MachineB sitting on AUTH domain with string LDAPServer = "AUTH", it shows the message 2f. User Not Found as the user returned in Step 2 is NULL. If I change string LDAPServer = "BUSINESS" then an exception is thrown in Step 1 that the domain controller cannot be found.
As a note the fact that LDAPServiceAccount can be a BUSINESS user shows that AUTH can see BUSINESS. If I change this to LDAPServiceAccount = "BUSINESS\\NotRealName" then Step 1 throws an exception with invalid credentials. This suggests it has resolved the BUSINESS domain user to authenticate the call? If I change LDAPServiceAccount = "AUTH\\ValidAccount" I get the same issue of User == NULL and so 2f. User Not Found.
namespace ConsoleApplication1
{
using System;
using System.DirectoryServices.AccountManagement;
class Program
{
static void Main(string[] args)
{
// Who are we looking for?
string userName = "BUSINESS\\User.Name";
// Where are we looking?
string LDAPServer = "AUTH";
string LDAPServiceAccount = "BUSINESS\\InternalServiceAccountName";
string LDAPServiceAccountPassword = "CorrespondingPassword";
Console.WriteLine("1. Connecting to: " + LDAPServer);
using (PrincipalContext adPrincipalContext = new PrincipalContext(ContextType.Domain, LDAPServer, LDAPServiceAccount, LDAPServiceAccountPassword))
{
Console.WriteLine("2. Finding: " + userName);
using (UserPrincipal user = UserPrincipal.FindByIdentity(adPrincipalContext, userName))
{
if (user == null)
{
Console.WriteLine("2f. User Not Found!");
Console.ReadKey();
return;
}
Console.WriteLine("3. Getting groups...");
using (var groups = user.GetGroups())
{
Console.WriteLine("4. The groups are:");
foreach (Principal group in groups)
{
Console.WriteLine("\t{0}", group.Name);
}
}
}
}
Console.WriteLine("END.");
}
}
}
I am wondering if this is an issue between the two AD Servers where the AUTH is not checking with BUSINESS but checking if the user exists on its configuration? Do I need to setup my LDAPServiceAccount user to have any special permissions? Any pointers would be much appreciated!
I guess you need to check pre-conditions while communicating with the AD server
(1) Your machine should be on the same domain to which you are communicating.
(2) Username and Password which you passed in query should exist on that AD server.
(3) In case you are updating records, then the credential you have passed to the server should have Admin rights.
Please check these points once.
Hope this helps you.
I search for a long time how I can define permitted logon hours on group like it is possible to do with user from the account tab in Active Directory.
I already have a class in c# that can make queries to returns a list of all permitted hours of a user with the help 'logonhours' properties.
public byte[] GetLogonHours(string userName, string password, string path)
{
DirectoryEntry entry = this.GetUserAccount(userName, path);
return (byte[])entry.Properties["logonHours"].Value;
}
public DirectoryEntry GetUserAccount(string username, string path)
{
using (DirectoryEntry objRootEntry = new DirectoryEntry(path))
{
using (DirectorySearcher objAdSearcher = new DirectorySearcher(objRootEntry))
{
objAdSearcher.Filter = "(&(objectClass=user)(samAccountName=" + username + "))";
SearchResult objResult = objAdSearcher.FindOne();
if (objResult != null)
{
return objResult.GetDirectoryEntry();
}
}
}
return null;
}
I used this post to help me understanding how I can query the logon hours:
http://anlai.wordpress.com/2010/09/07/active-directory-permitted-logon-times-with-c-net-3-5-using-system-directoryservices-accountmanagement/
It is important to understand that I don't want a feature to know when the last time a user has been logged. What I have is a feature that prevent a user logging at some moments.
What I want is a feature that can apply logon hours for a group of users and I can query the Active Directory with c# to get these logon hours information.
Thank you very much.
In my understanding logon hours information is a user information. As discribed in HOW TO: Limit User Logon Time in a Domain in Windows Server 2003 pointed by #Knite you can change it :
User by user, whatever if you loop on a list of user
Applying a GPO to an organizationalUnit users belongs to
In your case you can loop for all the members of a group and change their logon hours.
According to http://support.microsoft.com/kb/816666 , you should generate the list of users in a group and write their logon hours to a CSV file.
I need to create a new user in Active Directory. I have found several examples like the following:
using System;
using System.DirectoryServices;
namespace test {
class Program {
static void Main(string[] args) {
try {
string path = "LDAP://OU=x,DC=y,DC=com";
string username = "johndoe";
using (DirectoryEntry ou = new DirectoryEntry(path)) {
DirectoryEntry user = ou.Children.Add("CN=" + username, "user");
user.Properties["sAMAccountName"].Add(username);
ou.CommitChanges();
}
}
catch (Exception exc) {
Console.WriteLine(exc.Message);
}
}
}
}
When I run this code I get no errors, but no new user is created.
The account I'm running the test with has sufficient privileges to create a user in the target Organizational Unit.
Am I missing something (possibly some required attribute of the user object)?
Any ideas why the code does not give exceptions?
EDIT
The following worked for me:
int NORMAL_ACCOUNT = 0x200;
int PWD_NOTREQD = 0x20;
DirectoryEntry user = ou.Children.Add("CN=" + username, "user");
user.Properties["sAMAccountName"].Value = username;
user.Properties["userAccountControl"].Value = NORMAL_ACCOUNT | PWD_NOTREQD;
user.CommitChanges();
So there were actually a couple of problems:
CommitChanges must be called on user (thanks Rob)
The password policy was preventing the user to be created (thanks Marc)
I think you are calling CommitChanges on the wrong DirectoryEntry. In the MSDN documentation (http://msdn.microsoft.com/en-us/library/system.directoryservices.directoryentries.add.aspx) it states the following (emphasis added by me)
You must call the CommitChanges method on the new entry to make the creation permanent. When you call this method, you can then set mandatory property values on the new entry. The providers each have different requirements for properties that need to be set before a call to the CommitChanges method is made. If those requirements are not met, the provider might throw an exception. Check with your provider to determine which properties must be set before committing changes.
So if you change your code to user.CommitChanges() it should work, if you need to set more properties than just the account name then you should get an exception.
Since you're currently calling CommitChanges() on the OU which hasn't been altered there will be no exceptions.
Assuming your OU path OU=x,DC=y,DC=com really exists - it should work :-)
Things to check:
you're adding a value to the "samAccountName" - why don't you just set its value:
user.Properties["sAMAccountName"].Value = username;
Otherwise you might end up with several samAccountNames - and that won't work.....
you're not setting the userAccountControl property to anything - try using:
user.Properties["userAccountControl"].Value = 512; // normal account
do you have multiple domain controllers in your org? If you, and you're using this "server-less" binding (not specifying any server in the LDAP path), you could be surprised where the user gets created :-) and it'll take several minutes up to half an hour to synchronize across the whole network
do you have a strict password policy in place? Maybe that's the problem. I recall we used to have to create the user with the "doesn't require password" option first, do a first .CommitChanges(), then create a powerful enough password, set it on the user, and remove that user option.
Marc
Check the below code
DirectoryEntry ouEntry = new DirectoryEntry("LDAP://OU=TestOU,DC=TestDomain,DC=local");
for (int i = 3; i < 6; i++)
{
try
{
DirectoryEntry childEntry = ouEntry.Children.Add("CN=TestUser" + i, "user");
childEntry.CommitChanges();
ouEntry.CommitChanges();
childEntry.Invoke("SetPassword", new object[] { "password" });
childEntry.CommitChanges();
}
catch (Exception ex)
{
}
}