Get Active Directory GUID from SQL Server - c#

I'm getting User GUID from Active Directory in C# using the code below:
var GUIDID = "";
using (var domainContext = new PrincipalContext(ContextType.Domain, domain))
{
using (var user = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userNameToUse))
{
if (user != null)
{
GUIDID = user.Guid.ToString();
}
}
}
So the output from the code above for a particular person is:
7b8b17f1-9997-46ac-bec4-c747eed2de33
What I now want to do is query Active Directory from SQL Server 2008 using that GUIDID. However, the issue I'm running into is I don't know the name of the column.
I tried to search for the same person (using their full name) from SQL using the code below:
SELECT cn, objectGUID
FROM 'LDAP://xxx.local/OU=xxx Users,DC=xxx,DC=xxx'
WHERE objectClass = 'User' AND cn = 'John Smith'
Yet, objectGUID, OBjectSID are not the same as the GUIDID my C# code is returning.
I also tried to select * in my SQL query, but it only returns the path.
Any suggestion on how I can find out the GUID COLUMN name from SQL Code?
Thanks

The solution is really simple. I needed to convert the ObjectID
SELECT CONVERT(UNIQUEIDENTIFIER,0xF1178B7B9799AC46BEC4C747EED2DE33);
Hope it helps somebody.

Related

Npgsql CREATE USER using ExcuteNonQuery parameter

Hi I am trying to use SQL CREATE USER with NpgsqlParameter (to prevent sql injection):
var p = new NpgsqlParameter("p1", "testuser");
using (var cmd = new NpgsqlCommand("CREATE USER #p1", (NpgsqlConnection)sqlConn))
{
cmd.Parameters.Add(p)
cmd.ExecuteNonQuery();
}
I get a run time error
syntax error at or near $1
Can anyone help me out please?
Alas, you can't use binding variables with CREATE USER. To prevent sql injection use quotation: "me; delete from myTable" -> "'me; delete from myTable'":
string userName = ...
using (var cmd = new NpgsqlCommand(
$"CREATE USER '{userName.Repace("'", "''")}'",
(NpgsqlConnection)sqlConn)) {
cmd.ExecuteNonQuery();
}
Here we double each apostrophe which is within userName and then wrap chnaged name into apostrophes

Change user password for Oracle database using sql statement in C#

I'm working on a requirement where I have to change the oracle connection password of the current user from my application.
I have found that I can use the following statement to achieve this task using SQL:
ALTER USER *username* IDENTIFIED BY *password*
However because the username and password aren't sent to the database as quoted strings, I can't use bind parameters. (Which is also stated by this answer)
I have a working solution when I concatenate a string and sent it as a regular sql query over my Entity Framework DbContext instance like this:
using (var context = _dbContextFactory.CreateContext())
{
await context.Database.ExecuteSqlCommandAsync(
$"ALTER USER {username} IDENTIFIED BY \"{newPassword}\"");
}
The downsides of this approach is that by concatinating the password in the string I have SQL injection vulnerabilities and the user can't use some reserved characters in their passwords, like e.g. ; and "
I'm not concerned about the username parameter because this is managed within the backend code, however the password is directly from user input.
Is there any way to change the current users password in the Oracle database from C# using a safe approach? I'm also open to other approaches like a diffrent method or creating a stored procedure in the database, as long as it can be implemented in a C# client application.
We are using Oracle version 12+, so I can't use the IDENTIFIED BY VALUES '' syntax
For username we have to provide Oracle Identifier (in case we keep the original query) which is
Up to 30 characters in length
Must start with a letter
Can include $ (dollar sign), _ (underscore), and # (hash sign)
we can validate provided value via regular expressions:
if (!Regex.IsMatch(username, #"^[A-Za-z][A-Za-z0-9_#\$]{0,29}$")) {
// username is invalid
}
For the password we can
Double all quotations: my"password -> my""password
Ensure that the password contains valid characters only (e.g. let's exclude unicode control characters like back space and other)
So the code will be something like this
if (!Regex.IsMatch(username, #"^[A-Za-z][A-Za-z0-9_#\$]$")) {
// username is invalid
}
if (string.IsNullOrEmpty(newPassword) || newPassword.Any(c => char.IsControl(c))) {
// password is invalid
}
using (var context = _dbContextFactory.CreateContext()) {
await context.Database.ExecuteSqlCommandAsync(
$"ALTER USER {username} IDENTIFIED BY \"{newPassword.Replace("\"", "\"\"")}\"");
}
This seems to be working on my local Oracle test db (from ODP.net driver). The important bit seemed to be BEGIN / END; (wouldn't work without it).
using (var con = (OracleConnection)db.Server.GetConnection())
{
con.Open();
//string pw = "'''';++";
string pw = "newpass";
var cmd = new OracleCommand(#"
BEGIN
EXECUTE IMMEDIATE CONCAT('ALTER USER B identified by ',:pw);
END;", con);
cmd.CommandType = CommandType.Text;
var p2 = cmd.CreateParameter();
p2.ParameterName = "pw";
p2.Value = pw;
p2.DbType = DbType.String;
cmd.Parameters.Add(p2);
cmd.ExecuteNonQuery();
}

Verify if username exists when updating username

In this situation, there is a form used for updating user information (username, password, mobile number, etc.).
Below is the code I used to check if the username exists in the database:
string sql = "SELECT username FROM (SELECT username FROM useraccount WHERE username != #old_uname)ua WHERE BINARY username = #new_uname LIMIT 1;";
MySqlCommand cmd = new MySqlCommand(sql, SecurityMod.dbconn());
cmd.Parameters.AddWithValue("#old_uname", old_uname);
cmd.Parameters.AddWithValue("#new_uname", new_uname);
if (cmd.ExecuteScalar() == null)
{
isValidNewUname = true;
}
It works if the user really changes his/her username. But the problem occurs when the user made changes to anything but the username field. The isValidNewUname variable remains false. Any ideas and suggestions would be a big help.
Instead of basing on fetched username, I opted instead for the uid. I solved the problem with the following code:
string sql = "SELECT uid FROM useraccount WHERE BINARY username = #new_uname;";
MySqlCommand cmd = new MySqlCommand(sql, SecurityMod.dbconn());
cmd.Parameters.AddWithValue("#new_uname", new_uname);
if (cmd.ExecuteScalar() == null || cmd.ExecuteScalar().ToString() == userID)
{
isValidNewUname = true;
}
This code is shorter and more simple hence easier to maintain. What happens here is that the query looks for the uid of the #new_uname in the database. It then compares the fetched uid to the uid of the current user. If it is the same, it means that the fetched result of the query is simply the user itself, so it doesn't really matter if their the same or not since it belongs to only one user. If the fetched uid is not equal to the uid of the current user, it means the username input by the user is already taken so isValidNewUname would be false. If the query above doesn't return results, then the #new_uname is available since it doesn't have a record in the database.

UWP - Check if table exists

There is a lack of documentation for SQLite in C# on the SQLite website related to the "SQLite for Universal Windows Platform" extension available in VS2015.
Has anyone seen any documentation specific to this extension?
I am trying to see whether a table exists in my DB but cannot find a method to do this.
This is what I am doing and why:
SQLite.Net.SQLiteConnection conn;
string path = path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "entries.sqlite");
if (!System.IO.File.Exists(path))
{
conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), path);
conn.CreateTable<Entry>();
}
else
{
conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), path);
}
I do this because when this is executed:
conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), path);
The file is created if it does not exist. So first I need to test whether it exists. My assumption is that if the file exists, my table exists, because there is no scenario where the table is not created right after the file is created.
Am I missing some more direct way of testing for the table within the scope of the methods provided?
Thanks!
PS. I have checked whether my question has been answered but have not found anything related directly to this API.
You can use a query of the system sqlite_master table to see if a table with a given name exists:
var tableQuery = "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='Entry';"
bool tableExists = conn.ExecuteScalar<int>( tableQuery ) == 1;
If the table is not present, the query will return 0, if it is present, it will return 1.
However, you don't have to worry about calling conn.CreateTable<Entry>(); even when the table already exists. SQLite.net is smart enough to create the table only when it does not exist yet. If the table is already in the database, this call will be ignored.
Generic solution:
public bool TableIsExists<T>(SQLiteConnection conn)
{
var q = "SELECT name FROM sqlite_master WHERE type='table' AND name=?";
var cmd = conn.CreateCommand(q, typeof(T).Name);
return cmd.ExecuteScalar<string>() != null;
}

Backup SQL Server Schema With Data

I've been tasked with creating a backup of the data in our "default schema" database dbo to the same database using a new schema called dbobackup.
I honestly do not understand what this means as far as a database goes. Apparently, it is like having a database backup inside the existing database. I guess there is some advantage to doing that.
Anyway, I can't seem to find anywhere online that will allow me to do this.
I have found a few posts on here about copying the schema without data, but I need the data too.
Backup SQL Schema Only?
How do I check to see if a schema exists, delete it if it does, and then create a schema that accepts data in the current database?
Once I have the new schema created, can I dump data in there with a simple command like this?
SELECT * INTO [dbobackup].Table1 FROM [dbo].Table1;
That line only backs up one table, though. If I need to do this to 245 tables for this particular customer, I'd need a script.
We have several customers, too, and their databases are not structured identically.
Could I do something along these lines?
I was thinking about creating a small console program to walk through the tables.
How would I modify something like the code below to do what I want?
public static void Backup(string sqlConnection)
{
using (var conn = new SqlConnection(sqlConnection))
{
conn.Open();
var tables = new List<String>();
var sqlSelectTables = "SELECT TableName FROM [dbo];";
using (var cmd = new SqlCommand(sqlSelectTables, conn))
{
using (var r = cmd.ExecuteReader())
{
while (r.Read())
{
var item = String.Format("{0}", r["TableName"]).Trim();
tables.Add(item);
}
}
}
var fmtSelectInto = "SELECT * INTO [dbobackup].{0} FROM [dbo].{0}; ";
using (var cmd = new SqlCommand(null, conn))
{
foreach (var item in tables)
{
cmd.CommandText = String.Format(fmtSelectInto, item);
cmd.ExecuteNonQuery();
}
}
}
}
SQL Server already has this built in. If you open SQL Server Management Studio and right click on the database you want to back up, then select all tasks then backup, you will get an option to back up your database into an existing database.
This is the important part and why you should use the built in functionality: You must copy the data from one DB to the other DB in the correct order or you'll get foreign key errors all over the place. If you have a lot of data tables with a lot of relationships, this will really be hard to nail down on your own. You could write code to make a complete graph of all of the dependencies and then figure out what order to copy the table data (which is essentially what SQL Server already does).
Additionally, there are third-party programs available to do this type of backup as well (see: Google).
This is sort of a "work in progress" approach I got started with that looks promising:
public static void CopyTable(
string databaseName, // i.e. Northwind
string tableName, // i.e. Employees
string schema1, // i.e. dbo
string schema2, // i.e. dboarchive
SqlConnection sqlConn)
{
var conn = new Microsoft.SqlServer.Management.Common.ServerConnection(sqlConn);
var server = new Microsoft.SqlServer.Management.Smo.Server(conn);
var db = new Microsoft.SqlServer.Management.Smo.Database(server, databaseName);
db.Tables.Refresh();
for (var itemId = 0; itemId < db.Tables.Count; itemId++)
{
var table = db.Tables.ItemById(itemId);
if (table.Name == tableName)
{
table.Schema = String.Format("{0}", DatabaseSchema.dboarchive);
table.Create();
}
}
}
The only issue I am currently running into is that my db variable always comes back with Tables.Count == 0.
If I get a chance to fix this, I will update.
For now, I've been told to remove this piece of code and check my code in.

Categories