Hadoop giving AccessControlException - java

I am trying to write a file to HDFS cluster from My windows machine but getting following error
org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.AccessControlException):
Permission denied: user=..., access=WRITE ,
inode="/user/hadoop/Hadoop_File.txt":hdfs:hdfs:-rw-r--r--
In my hadoop configuration
hadoop.security.auth_to_local is set to DEFAULT
hadoop.security.authentication is set to SIMPLE
if i mention user name as "hdfs" by doing
System.setProperty("HADOOP_USER_NAME", "hdfs");
everything works fine .
but if the policy is simple it means no authentication it should allow any user to create file
Help me in understanding why this is happening

I got the answer :) you have to configure dfs.permissions.enable = false ,it was true in my case once it is turned off ,it doesn't complains for any user used

Simple authentication in Hadoop means you don't need to prove who you are, for example with a password or token, but you still need to say who you are. Whichever user you assert yourself to be, Hadoop will believe you and adopt user name for the operation you request.
There are still permissions in place on HDFS (you can see that with hdfs:hdfs:-rw-r--r-- in your message above), so you need to assert yourself to be a user who has the necessary permissions for your operation, which is what you did with System.setProperty("HADOOP_USER_NAME", "hdfs");
The short version is, identity is not the same as authentication :)

Related

Connection with TN5250j works while IBMi access v1r1 (and JT400 library) does not

Few days ago my correctly working java application stated to throw "General security error" while connecting to AS400. I use JT400 library for connect. After some debugging I also find out I cannot connect with IBMi access v1r1 (5250 emulator from IBM). System i Navigator also does not work. This is print screen from login (errors are same for java application):
But connecting with TN5250J emulator works! I guess problem is with "Not authorized to object /QSYS.LIB/EN_US.LOCALE". I tried connecting with two users. One is my programming user and it works normally when connected through TN5250J. Other one is database access user that I cannot check because it has disabled access through terminal. Using same application on different system (V5R4) works correctly. Looking into job log I found nothing.
Why is /QSYS.LIB/EN_US.LOCALE accessed during signon (and it is not accessed from TN5250J)? What could affect signon process so that it no longer works with IBM emulator/library while it still works with TN5250J? Are there some connection properties in JT400 library that could affect what happens during signon so I could connect like with TN5250J?
Also please someone create tag TN5250J. I think it should be here and I have no reputation to create it!
Solution in article suggested by JamesA works. Our admin did it and I have my access back. But our admin has no idea how issue was created in the first place.
Solution from article:
Execute the Work with Object Links command (WRKLNK) to view the Root (/) directory of the AS/400 IFS.
WRKLNK OBJ('/')
In front of the AS/400 IFS directory object (specified by a single '/'), enter a '9' to work with the Root (/) object's authority.
If *PUBLIC authority is equal to *EXCLUDE, place a '2' in front of the *PUBLIC entry, press enter and add the following authorities for the *PUBLIC user:
Under the New Data Authorities parameter (DTAAUT), enter *RWX so that the user has read, write, and execute in the Root (/) directory.
Under the New Object Authorities parameter (OBJAUT), enter the following authorities:
*OBJMGT: Object management authority
*OBJEXIST: Object existence authority
*OBJALTER: Object alter authority
*OBJREF: Object reference authority
Press Enter and save your changes.
TN5250J worked because error does not happen during login (for example through green screen) but instead it happens during initialization - when you start IBMi Access and GUI window will sometimes prompt for login. Since TN5250j does not do this it works. In IBMi Access when in first prompt I specify user with *ALLOBJ authority I can then login through green screen normally with my normal user. JT400 library probably just combines logic for initialization and login!

Java application authentication using Active Directory

I am working on a third party Java application for which I need to authenticate its users using Active Directory.
This application is hosted on RHEL 6.5, and uses LDAP to authenticate with Windows Active Directory. The AD server has been set up, and is working fine with an earlier version of the application (which was configured to enable the integration).
For the newer version, the vendor has laid out some steps to modify/configure the application files to connect with the AD server, and which are expected to help us authenticate. After making required changes, we are only able to open the UI page, which does not accept the (correct) credentials, the page that helps us with application configuration is not accessible at all.
I am a newbie to this area, and as far as my understanding goes, I would just need to make the suggested changes, and not follow the steps presented in this document, as those are for authenticating the Linux users, and NOT the application's users. Could someone also please confirm the same.
Any help/guidance in this issue would be greatly appreciated.
Thanks very much!
Edit:
I am unable to provide details of the files as it is confidential property, but the changes have to be made in the server property files.
Kindly request more details if necessary, I will try my best to provide them as I can't disclose everything, citing confidentiality reasons.
Thank you very much.
Edit 2:
Have added more details with this edit, which are given below:
The application has one of its component as CAS, which is currently configured to use database as its authentication handler. When we enter the credentials - username: abcd, password: samplepswd, we are able to login successfully.
As the business requirement is that of authentication with Active Directory using LDAP, we have to modify the CAS properties file. As per instructions from the product vendor, we have changed the following properties to use ldap -
authenticationHandler.type=ldap
ldapSSLConfig.enabled=false
ldapContextSource.url=ldap://sample.ADserver.example.net:389
ldapContextSource.userDn=abcd
ldapContextSource.password=samplepswd
ldapAuthenticationHandler.filter=uid=%u
ldapAuthenticationHandler.searchBase=OU=DEF,OU=PQR,OU=XYZ,DC=ADserver,DC=example,DC=net
We also need to make changes in the casAuthConfig xml file for the following properties (as anonymous search is not supported):
1. anonymousReadOnly, value is set to false
2. java.naming.security.authentication, value is set to simple
There is provision to use ldap over SSL as well, but currently we are not using that.
However, if we do use SSL, additional changes have to be made to the following properties:
ldapSSLConfig.enabled=true
ldapSSLConfig.trustStorePath=/home/dir1/subdir1/subdir2/keystorename.keystore
ldapSSLConfig.trustStoreType=jceks
These are the only configuration changes done on our (client) side; and in fact the only changes done. Nothing has been added/modified on the server (AD server), except another user, but that has no impact on the existing setup.
After restarting cas to reflect the changes, we encounter the error of bad credentials, although the values entered are correct:
2015-09-16 12:12:30,558 INFO [com.emeter.cas.authentication.support.DelegatingAuthenticationHandler] - Authenticating credential using handler
com.emeter.cas.adaptors.ldappwd.BindLdapAuthenticationHandler
2015-09-16 12:12:30,558 DEBUG [com.emeter.cas.authentication.support.DelegatingAuthenticationHandler] - credentials.getUsername() = abcd
2015-09-16 12:12:30,672 INFO [com.emeter.cas.adaptors.ldappwd.BindLdapAuthenticationHandler] - Search for cn=abcd returned 0 results.
2015-09-16 12:12:30,672 INFO [org.jasig.cas.authentication.AuthenticationManagerImpl] - AuthenticationHandler:
com.emeter.cas.authentication.support.DelegatingAuthenticationHandler failed to authenticate the user which provided the following credentials:
[username: abcd]
2015-09-16 12:12:30,676 ERROR [org.jasig.cas.integration.restlet.TicketResource] - error.authentication.credentials.bad
org.jasig.cas.ticket.TicketCreationException: error.authentication.credentials.bad
at org.jasig.cas.CentralAuthenticationServiceImpl.createTicketGrantingTicket_aroundBody10(CentralAuthenticationServiceImpl.java:423)
Can anybody please help with this issue? Or possibly point in the right direction?
Any help would be greatly appreciated.
Thank you.

Malformed PAC logon info on new KerberosToken

I'm using the code here to get authentication information from a Kerberos token. In there I've configured the domainUsername and domainUserPassword and just ran it as specified in the readme.md.
Then, from a browser that is in the AD domain, I connect to http://server:8080/spnego and I see on the opened page my username#domain. The page should also contain the SID of the AD groups to which my user belongs.
Looking at the server logs, I see:
org.jaaslounge.decoding.DecodingException: Malformed PAC logon info.
at org.jaaslounge.decoding.pac.PacLogonInfo.<init>(PacLogonInfo.java:209)
at org.jaaslounge.decoding.pac.Pac.<init>(Pac.java:45)
at org.jaaslounge.decoding.kerberos.KerberosPacAuthData.<init>(KerberosPacAuthData.java:13)
at org.jaaslounge.decoding.kerberos.KerberosAuthData.parse(KerberosAuthData.java:21)
at org.jaaslounge.decoding.kerberos.KerberosRelevantAuthData.<init>(KerberosRelevantAuthData.java:41)
at org.jaaslounge.decoding.kerberos.KerberosAuthData.parse(KerberosAuthData.java:18)
at org.jaaslounge.decoding.kerberos.KerberosEncData.<init>(KerberosEncData.java:136)
at org.jaaslounge.decoding.kerberos.KerberosTicket.<init>(KerberosTicket.java:103)
at org.jaaslounge.decoding.kerberos.KerberosApRequest.<init>(KerberosApRequest.java:62)
at org.jaaslounge.decoding.kerberos.KerberosToken.<init>(KerberosToken.java:52)
at com.example.ManualSpnegoNegotiateServlet.attemptNegotiation(ManualSpnegoNegotiateServlet.java:271)
Line 271 is the following
KerberosToken token = new KerberosToken(kerberosTokenData, keys);
That error message is too vague. I've no idea how to continue and I get the same error from different clients.
Does anyone have any tip about this?
I've figured this one out myself. It turns out that the message "Malformed PAC logon info" is actually correct. The code failed when it was trying to get the "Resource groups data".
Initially I thought that the PAC_LOGON_INFO structure has changed since the last jaaslounge implementation was written (somewhere in 2010). I thought that because the MS-PAC specification does not mention it at all.
Actually, the problem is coming from a completely different place: the KDC. It's running on a Win Server 2012, version in which Microsoft added by default resource SID Compression.
There you have it, if you turn off resource SID Compression on the KDC, everything will start working (no need to touch anything else, i.e. the version of jaaslounge or to patch hava with an unlimited JCE policy).

Web Application Password Security

My company has a Java Web Application with the database password stored in a properties file and we need to secure the password. I've googled and found the Jasypt solution, but in my mind that doesn't really solve the problem because that requires another password to feed to the application and I don't know how to secure that password.
The main suggestion for Jasypt is to feed the password in as an environment variable, which means that in the best case scenario I would be starting the application like:
./myApp -D password=myPasswordDontHackPlz
which isn't secure because you can see the password when you do
ps -ef | grep myApp
We also can't feed the password in when it needs it (via a the web or something) because it essentially decides when it needs the password, and it needs it pretty often.
Is there any solution to this or am I asking for some magical solution that doesn't exist? I don't like Jasypt because it seems to me to essentially just be obfuscation, and I'm not after obfuscation i'm looking for true security here.
Why don't you put the password in a properties file which is only readable by the user that runs the web application? The web application will need to know the root password at some stage, so obviously you want it to be able to read/use it. What you want is that noone else should be able to read it, and protecting the file will do it.
This is all assuming that you need to externalize your password. You could hardcode it into the application if you wanted to make it harder to get at, but someone with access to the JAR can always decompile your classes.
I am just wondering - storing a root database password is a bad idea in general. But then again, when someone actually manages to get access to that file on the server, how safe is your database anyway?
Would the password still show up if you created a shell script and run it instead?
#!/bin/bash
./myApp -D password=myPasswordDontHackPlz

How to get windows user name in java

I write a web application I have to do signin in that using the windows username..
I tried to get username using system.get property() but its giving the username of server windows name only.but I want to the username of client system..can any one help me?
If I understood you correctly you want to sign in to the web application using the Windows credentials. If so - the problem is that the server machine knows nothing about the client. It can provide you the user info only after successful login (see Get windows username using JAVA or JSP).
You could point your system to some user store (e.g. LDAP) that will be used by both Windows system and your app. In this situation you will be able to sign in to the app using Windows credentials.
The Browser is an application to generate the view based on an HTML code. It wont give access to the client machine.
You can use request.getRemoteUser() to get the user name, that too is possible only if its allowed in the client machine.
If your client is running on a windows machine you can get the user name using this
var wshshell=new ActiveXObject("wscript.shell");
var username=wshshell.ExpandEnvironmentStrings("%username%");
This is a solution for getting the user name, but i will never recommend this, it surely is a bad practice.
Is the entire Java application running on the server? How would your application even know about a specific client machine? And how would it deal with concurrently logged in users? And how would it deal with a primitive client machine which does not have a notion of a user name?
You can instead run a Java applet which is invoked on the client's machine. You could the send this information to the server to process. However, your users would most likely not like that and not grant the required privileges.
Alternatively, you could try to use JavaScript to read the user name, in case that you are communicating via a webpage. I want to stress the word try in this context since there is not universally functional approach and most users will most likely not allow you to read this property either.
In a nutshell: Users do not normally want to share this information with you and therefore you cannot access it. If you could, you would have found a security hole which would most likely get fixed. Rather, ask your application's users to enter a name to use for whatever reason you would require it. Or, if this is an option, organize for example your Windows credentials in a service that can be accessed by a standardized API.

Categories