I have SMO code which copies tables from one database to another. It runs fine in a desktop app. The same exact code put in a service, gives an error. The error is really obscure and doesn't hint about permissions.
I was wondering if the SMO objects need any kind of security to be used. Security context? Windows credentials.. etc? I am not talking about SQL Server security but security surrounding the use of the SMO methods.
You need full trust. You may have problems running this on certain hosted ASP.NET accounts, apps downloaded from the internet, or from shared drives, where CAS kicks in and gives the code something less than full trust and certain APIs won't be callable.
Are you using integrated security with your connection? If so, make sure the credentials that the service is running under have necessary access.
Make sure your service account (the account that your windows service is running as) has "Act as Part of Operating System" Policy.
Related
Okay all, the subject is a pretty poor one, but I'm not sure how else to put it. I have Server 2012 with a bunch of jobs, all owned by sa. They all worked fine ever since I began working here in January 2016, but we recently made major changes to our servers. Currently, we have a few servers off the domain, and set up together as a workgroup. They're clones of what we were running before the shakeup, so include all the data/logins. The main difference is that they can't talk to our Active Directory anymore.
Back to SQL Server. Some of the jobs on the server have to read from and write to an FTP folder on one of the servers which is in the same workgroup. That is, both the 2012 server and the FTP server are on the same workgroup, so should talk to each other with no problem. However, some of the jobs keep failing because of logon errors when trying to connect to the FTP server. I'm not using FTP, but rather network locations, like \\1.2.3.4\ftp\folder\file.txt in my job code. This worked perfectly until the servers moved. Skipping the long and confusing reasons why, suffice it to say that this server won't be back in contact with Active Directory for some time. Indeed, letting it be so can't happen until we can shut down its on-domain counterpart. However, we can't do that until I get this working sans domain contact. Again, long story behind that catch-22.
My questions after dealing with all this are:
If the job in question is owned by sa, why do the logs show logon attempts by nt access\network authority?
How/where can I change the username/password the 2012 server is using to talk to the FTP server?
Is there a way I could access the FTP server, given the workgroup setup in place, that's easier than what I'm trying to do now? Sharing settings on the FTP folder, for instance?
Thanks for any explanations anyone can offer. I'm thoroughly confused about permissions, accounts, credentials, and remote access and have no idea where to turn, having googled all of this exhaustively.
I have not worked with servers that were not domain joined, but I have had similar issues when using SSIS accross sub-domains (see original answer below for more detail). I would look at the setup of sql server and see what service accounts were used for the sql database service and the sql agent service (check out https://msdn.microsoft.com/en-us/library/ms143504.aspx). ALso, make sure that the server accounts have permissions to the file system locations (you likely already did that, but just in case).
Original Answer for SSIS Situations ( I misunderstood that the asker wasn't using SSIS):
You might need to set up a proxy to control what account is used. There is a section on proxies in this article that you might find helpful. I suggest reading the entire article, it might shed some light.
https://www.simple-talk.com/sql/database-administration/setting-up-your-sql-server-agent-correctly/
Background
My project is using Entity Framework
Migrations are being deployed via OctopusDeploy by using the migrate.exe executable
Problem / Goal
I need to script a set of permissions to the database for an account on each system, e.g.
When deployed to dev, account1 must be granted datareader/datawriter access
When deployed to test, account2 must be granted datareader/datawriter access.
etc.
I'd like to use the same system for this that we're using so far (manual code-based migrations). If possible, I'd like to script the permission grants for a database and run them as part of our migrate.exe execution on deployment.
However, because I'll only have one "migration" that applies these permissions, I don't know to ensure I apply the right permissions to the right user in each environment.
Questions
Is there a recommended way to know or apply which environment the migrations are a part of when running migrate.exe so that I can run it against all environments without issue?
Can I pass in some sort of variable to migrate.exe which I can then use in my migrations?
Is there something wrong in my premise / assumptions when approaching this?
I have created an SQL database file in Visual Studio for my ASP.NET MVC 3 project. How do i password protect my SQL database file?
Hackers can't get access to the file itself, if your host has any brains whatsoever.
And even if they could, they'd need some way to shut down SQL Server so they could obtain the file directly.
What you need to concern yourself with is:
Setting up a very strong password for your web application user,
giving the web user extremely limited rights (principle of least
privilege),
ensuring that the host places the database on a separate
server that is protected from the outside world, and
making sure your
app isn't lazy about preventing SQL injection (e.g. use parameterized
statements).
I'm wondering what techniques you use to store the database credentials for your application. I'm specifically concerned with java webapps, but I don't think there's any need to limit the questions to that.
things to consider:
Do you use property files,xml configs, other?
Is it bundled into your application(ie in a jar file) or stored seperately on the file system somewhere?
Is the password encrypted? If so, what encryption scheme do you use?
Since you're leaving the question open to platform, I'll add that database credentials for .NET apps are stored in the web.config file. From version 2.0 and above, there is a specific ConnectionStrings section that allows for easier programmatic access to the connection string.
In addition to having IIS automatically block direct requests to the web.config file by default, you can also use an IIS command to encrypt the ConnectionString section of the web.config file. This encryption is machine specific, adding to its strengths, and the .NET runtime will also decrypt the connection string on the fly when you access it, so there is no need for additional coding in your application to work with it.
With Java, database connection pools should be passed into webapps by the container. This is in the standard declarable in WEB-INF/web.xml as resources. The same applies to mail sessions and other external resources that may vary from installation to installation. Look up JNDI for more information on this)
The nice part with this is that the application doesn't care about how to actually connect to anything outside. It will not see any passwords, because the container itself will use them.
In tomcat this is configured either from context files (e.g.) in conf/Catalina/localhost/ , conf/server.xml or - preferably only for dev environments, from the webapps META-INF/context.xml. Other environments have their own configuration location or application.
The encryption of passwords actually depends on the container. Tomcat stores them in plaintext, but the application itself won't see it. I don't know about the mechanics in other environments.
On the Microsoft stack, things can be very nice.
You create a network user account in Active Directory with almost no permissions. You configure IIS to run your webapp as that user. You grant that user read access to the web folders and files on the disk. You configure SQL Server to grant that user read/write permissions on the tables you want. And in the connection string, you instruct the db client to connect as the user account which the webapp is currently being run as.
There is only one actual user account, although it is visible in multiple places. This user account has extremely limited permissions. There is no storing passwords anywhere, even if encrypted. There is no configuration that has to be done in code for this to work (it's all in setting up the permissions).
Depends on the app server.
I usually use JNDI lookups for the data source, so credentials are stored on the app server that handles the connection pool. No need to put anything other than the JNDI name in configuration that way.
Yes, the password is encrypted on WebLogic.
On Tomcat things can be dicey. Connection info is in META-INF/context.xml, which means plain text for the password. I only do that for development, never in production.
In Django, the credentials are in your settings.py configuration file. Since this is not generally kept in your /var/www/ directory tree, it's very safe.
Also, a single Django application may be used (and reused) for many web sites or web servers on the same host, each with it's own distinct settings. So the settings.py configuration is not bundled with the app, but is part of a single deployment of the app.
For asp.net:
I store global parameters such as the connection string and repository paths in the Registry and then a reference to the registry entry in the web.config.
The main reason being that I often find I have to write a stand alone executable to run background tasks and other automated features that require access to the same parameters. Therefore keeping everything that is truly global in one easily accessible place makes for an easier life.
As stated before, no platform specified, and using some ideas from earlier answers:
I am considering a containerised application. You could store the password for the database in a file in the container. The first step of your application would be to establish the database connection, even before listening on web requests. With a successful db connection the file with the credentials is deleted and the variables containing the these, are removed. So when you start serving requests, the only thing that remains, is an open database handle to use from this moment on. If for any reason the database connection is lost, you simply quit and wait to restart the container, the credentials file will be there again.
Which of these are good places to keep your web app’s database credentials?
In a separate file in your source code
In a separate file on your web server host
In your database
None. The database credentials should never be stored
So our web server apps need to connect to the database, and some other apps have startup scripts that execute at boot time.
What's the best way to store the name/password for these applications, in terms of
security, e.g. perhaps we don't want sysadmins to know the database password
maintainability, e.g. making the configuration easy to change when the password changes, etc.
both windows and linux solutions appreciated!
The best way to secure your password is to stop using one. Use a trusted connection:
How To: Connect to SQL Server Using Windows Authentication in ASP.NET 2.0.
Then you have nothing to hide - publish your web.config and source to the world, they still can't hit your database.
If that won't work for you, use the built in configuration encryption system in ASP.NET.
PostgreSQL offers a nice solution for this kind of situation in their documentation. Essentially, you use ssh to bridge a port on your machine to the PostgreSQL server port on the remote machine. This has three stages of authentication:
Restrict access to the local port, such as only letting a particular user connect to it.
Set up password-less connection to the PostgreSQL host with ssh as a particular user.
Allow the user ssh connects as to have local access to PostgreSQL without a password.
This reduces the security to whether your user accounts are secured and your ssh configuration is sound, and you have no need of a password stored anywhere.
Edit: I should add that this will work with any database that listens to a TCP/IP port. It just happens to be described in PostgreSQL. And you will want iptables (or the equivalent off Linux) to do the port restrictions. See this.
I agree with lomaxx: if somebody is already on the server or has wide ranging access to it (like a sysadmin), the game is pretty much over. So the idea would be to use a server you trust that it is secure to the degree you want it to be. Specifically:
You need to trust the sysadmins
You need to trust anybody else who is running code on the same server (this is why shared hosting is a big no-no for me)
Beyond that, environment variables seem to be a popular choice for storing these types of credentials, because this means that access to the source only (for example by compromising the dev box) doesn't reveal it directly and also it can be nicely localized for each server (dev, test, etc).
plain text? If they're on your server, I would hope the server is secure enough not to allow unauthorised access. If people can access your config files on the server, something has gone wrong much earlier.
clarification: in terms of security, maintainability (e.g. if the login needs to change, can I find it later, etc)
#lomax: perhaps I might not want everyone with access to the physical server (e.g. sysadmins) to see the password.
Thanks!
In most cases, I believe it is sufficient to obfuscate the password in a plain text file (eg. with base64). You cannot completely protect a stored password against a determined sysadmin with root access, so there's not really any need to try. Simple obfuscation, however, protects against accidentally revealing the password to a shoulder surfer.
A more complex alternative is to set up a dedicated secure password server that either:
provides a password decryption service
actually stores the passwords for use by other less secure servers
Depending on the network protocols used, this may not protect against a rogue sysadmin with tcpdump. And it probably won't protect against a determined sysadmin with a debugger, either. At that point, it might be time to look at something like Kerberos tickets.
You can bake a symmetric encryption key into your binary, and have that binary read an encrypted username/password from a file on disk when it starts up.
However, this is not really much more than obfuscation, since your code is likely to be stored in some source repository somewhere.
I would suggest that you would be better served to control access to your servers both physically and over the network using a firewall and a private network bubble, and store the passwords in the clear (or base-64 encoded) on disk with permissions locked down to the run user for your web app.
You can also lock down the database server to only accept connections from your web app machines by IP.
Ultimately, your problem is that the key (your DB username/password pair) needs to be available for programmatic, unattended use by your web apps.