Solved /etc/login.access configuration
I was messing with /etc/login.access to tighten login access to a machine I login to via ssh. This is what I did-
I can login OK over ssh as big_girl, but cannot su to root. Trying to su to root returns-
How can I modify the +:root:console line so that I can su to root?
EDIT: I should clarify- I do not have physical access to this machine. For security, I do not want to let root log in directly via ssh but rather allow root login only from another user in wheel.
Thanks for any help.
First, I wonder why you deny yourself local login (if I understand that EXCEPT syntax correctly). If a problem occurs with a computer, I much prefer loging-in as a user and try to isolate and fix the problem, and only switch to root if there’s no other way.
I’m not familiar with all the FreeBSD login security features, but a suggestion I could propose you is to enable remote root the same way you enable yourself (or perhaps restrict to some specific domain names), then block root login from ssh using the DenyUsers keyword in the /etc/ssh/sshd_config file. su will then work. I often switch to root this way via ssh !
First, undo all of your changes to /etc/login.access.
Next, open up /etc/ssh/sshd_config in your favorite text editor. Find the (commented out, by default) line that contains the » PermitRootLogin » directive.
It will read (by default) one of two ways (depending on FreeBSD version):
Uncomment it and set it to «no». That is, it should read:
Last, if there are only a few user accounts you wish to allow to login via SSH, I recommend adding them to a new group, and setting AllowGroups (instead of DenyGroups or DenyUsers ) in /etc/ssh/sshd_config.
Login access all exception
Exception Details: System.Data.SqlClient.SqlException: Login failed for user ‘name’.
Line 205: using (SqlCommand command = new SqlCommand(«GetNonEmptyAlbums», connection)) <
Line 206: command.CommandType = CommandType.StoredProcedure;
Line 207: connection.Open();
Line 208: List list = new List();
Line 209: using (SqlDataReader reader = command.ExecuteReader()) <
Source File: x:\Inetpub\name.domain\personal\mysite.name.domain\www\App_Code\PhotoManager.cs Line: 207
[SqlException (0x80131904): Login failed for user ‘name’.]
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +739123
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) +188
System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1956
System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK) +33
System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, Int64 timerExpire, SqlConnection owningObject) +170
System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(String host, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, Int64 timerStart) +349
System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance) +181
System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance) +170
System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection) +359
System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options) +28
System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject) +424
System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject) +66
System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject) +496
System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) +82
System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) +105
PhotoManager.GetRandomAlbumID() in x:\Inetpub\name.domain\personal\mysite.name.domain\www\App_Code\PhotoManager.cs:207
PhotoManager.GetPhotos() in x:\Inetpub\name.domain\personal\mysite.name.domain\www\App_Code\PhotoManager.cs:100
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) +0
System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) +72
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean skipVisibilityChecks) +296
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture) +29
System.Web.UI.WebControls.ObjectDataSourceView.InvokeMethod(ObjectDataSourceMethod method, Boolean disposeInstance, Object& instance) +482
System.Web.UI.WebControls.ObjectDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments) +2040
System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback) +17
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1360
«Login failed for user ‘user’.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Denying Access: AccessDeniedException
Keep on Learning!
If you liked what you’ve learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
Denying Access: AccessDeniedException¶
Let’s login as user again and surf to /new . Since we have the ROLE_USER role, we’re allowed access. In the access_control section of security.yml , change the role for this page to be ROLE_ADMIN and refresh:
This is the access denied page. It means that we are authenticated, but don’t have access. Of course in Symfony’s prod environment, we’ll be able to customize how this looks. We’ll cover how to customize error pages in the next episode.
The access_control section of security.yml is the easiest way to control access, but also the least flexible. Change the access_control entry back to use ROLE_USER and then comment both of them out. We’re going to deny access from inside our controller class instead.
Denying Access From a Controller: AccessDeniedException¶
Find the newAction in EventController . To check if the current user has a role, we need to get the “security context”. This is a scary sounding object, which has just one easy method on it: isGranted .
Use it to ask if the user has the ROLE_ADMIN role:
If the user doesn’t have ROLE_ADMIN , we need to throw a very special exception: called AccessDeniedException . Add a use statement for this class and then throw a new instance inside the if block. If you add a message, only the developers will see it:
In Symfony 2.5 and higher, there’s event a shortcut createAccessDeniedException method:
When we refresh now, we see the access denied page. But if we were logged in as admin , who does have this role, we’d see the page just fine.
AccessDeniedException: The Special Class for Security¶
Normally, if you throw an exception, it’ll turn into a 500 page. But the AccessDeniedException is special. First, if we’re not already logged in, throwing this causes us to be redirected to the login page. But if we are logged in, we’ll be shown the access denied 403 page. We don’t have to worry about whether the user is logged in or not here, we can just throw this exception.
Phew! Security is hard, but wow, you seriously know almost everything you’ll need to know. You’ll only need to worry about the really hard stuff if you need to create a custom authentication system, like if you’re authenticating users via an API key instead of a login form. If you’re in this situation, make sure you read the Symfony Cookbook entry called How to Authenticate Users with API Keys. It uses a feature that’s new to Symfony 2.4, so you may not see it mentioned in older blog posts.
Ok, let’s unbreak our site. To keep things short, create a new private function in the controller called enforceUserSecurity and copy our security check into this:
Now, use this in newAction , createAction , editAction , updateAction and deleteAction :
You can see how sometimes using access_control can be simpler, even if this method is more flexible. Choose whichever works the best for you in each situation.
You can also use annotations to add security to a controller! Check out SensioFrameworkExtraBundle.
Leave a comment!
Like always, great work on this tutorials.
I have a little problem with an automatic redirect by symfony. When I throw that AccessDeniedException to an anonymous user, besides of error page it gets a redirect to Login Page.
Is there a way to disable that redirect or something? I couldn’t find a solution on documentation =/
Thanks in advance ;]
Yes, this behavior is totally by design — it allows the user to get a chance to login to see a secured page. What’s your use-case for *not* doing this?
Either way, the whole point of throwing AccessDeniedException is to «redirect to login if they’re anonymous OR show them a 403 error page». If you don’t want this, you’re always free in a controller to simply return a Response object with a 403 status code (e.g. something like «return new Response(«get outta here», 403)». Of course, that means you won’t be using your *normal* Symfony 403 error page. If you try want to force a 403, but not do the redirect, throw an exception of the class Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException. If you want to know *why* that works, let me know ;).
Great! AccessDeniedHttpException was the key, I’m not getting redirected anymore.
Why is this working :)?
My reason is because my login form is inside an iframe, so I just can’t do a redirect. What I need is to show a message saying «You need to login first» and a button which opens the iframe, if login is successful, then redirect to the desired page.
You can see what I want to achieve in my small site ( https://www.esla.pro ) just click where it says «Inicia Sesion» at the top section.
I’m translating the whole site to symfony2 🙂
Thanks for your time.
For why is this working? There are two things happening:
1) AccessDeniedException is a very special exception. When you throw it, it triggers the part of Symfony that tries to get the user to login (usually by redirecting them to /login). Here’s the internals for that: https://github.com/symfony/.
2) If you throw any Exception, it usually triggers a 500. BUT, that’s not always true. If the Exception class you’re throwing implements a special HttpExceptionInterface (https://github.com/symfony/. , then you will not get a 500, but whatever status code returned by that class’s getStatusCode() method. The `AccessDeniedHttpException` is one of these: https://github.com/symfony/. . It causes a 403 status code, but doesn’t trigger the special behavior in (1).
About your situation, here’s my advice (fwiw):
1) Allow the user to be redirected to /login. This doesn’t mean you need to eliminate your iframe popup (keep reading), but *also* allow for the login to be its own page (you could have /login basically be a blank page that has some JS to open your popup, if you really want to — it looks like you’re doing something like this already: https://www.esla.pro/soport. . This will make your life much easier. One things Symfony already does is help redirect you back to the original page the user was trying to visit in this situation.
If anything, the piece you need to override is called the «Entry Point» — this is the class that’s called when Symfony says «the user is trying to access a protected resource, but they are not logged in, let’s help them!». This is the class that causes the redirect — the default one is here: https://github.com/symfony/. . You may use want to use your own, to, for example, redirect on normal requests, but return a normal 403 on AJAX requests. You could extend the FormAuthenticationEntryPoint class, register your new class as a service, then put your service id on the entry_point key under your firewall: http://symfony.com/doc/curr.
Phew! That’s a lot of info, but hopefully it’s useful!