Fetching LDAP Schema in Java - java

I'm trying to fetch the schema of an LDAP entity. I've been advised to use Novell's open sourced LDAP library, which seems to be quite good. I found an example called GetAttributeSchema, which sounds really good, but I think I've got a parameter set incorrectly or something.
The results I'm getting are:
ou ( 2.5.4.11 NAME ( 'ou' 'organizationalUnitName' ) DESC 'Standard LDAP attribute type' SUP 'name' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2256' )
objectClass ( 2.5.4.0 NAME 'objectClass' DESC 'Standard LDAP attribute type' EQUALITY 'objectIdentifierMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2256 (XXX: syntax should be ...38)' )
The results I'm expecting are [something to the effect of]:
cn
affiliations
streetaddress
phone
fax
etc
Just wondering if it's obvious to an LDAP expert what I'm missing or what I should be asking for.
Thanks!
==============================
SOLUTION:
ServiceableLDAPConnection lc = takeConnection();
LDAPSchema schema = lc.fetchSchema(lc.getSchemaDN());
Enumeration<?> enumeration = schema.getAttributeNames();
I found this site particularly useful: http://www.go4expert.com/forums/showthread.php?t=4814
==============================

You are getting the full schema definitions. Usually in LDAP queries for cn=schema, you get the entire schema as one object you will need to parse.

Related

Flexible search is asking for session country while called from REST api

I have a code which executes a flexible search. When i am calling that code locally to search data it gives expected output but when I try to call it using REST API (Through controller) it gives error as could not translate value expression 'session.currentCountry' but i am not even using session or session country anywhere in flexible search. what can be issue?
here is code
query
select {rr.pk} from {returnrequest as rr join order as r on {r.pk} = {rr.order} join orderstatus as os on {r.status}={os.pk} join basestore as bs on {bs.pk}={r.store} join returntype as rt on {rr.returntype} = {rt.pk} join paymentmode as pm on {pm.pk}={r.paymentmode} join returnstatus as rs on {rs.PK}={rr.status}} where {os.code} NOT in ('PENDING_PAYMENT','ON_VALIDATION', 'CREATED', 'IN_PROGRESS', 'ORDER_SPLIT','CANCELLED') and {rr.creationtime} >= ?returnCreationDateFrom and {rr.creationtime} < ?returnCreationDateTo and {bs.uid} in (?market) and {rt.code} in (?returnType) and {pm.code} = 'SplittedPaymentMode' and {rr.totalRefund} != 0.0 and {rs.code}!='RECEIVED' group by {rr.pk} ";
code
FlexibleSearchQuery query = new FlexibleSearchQuery(flexiQuery.toString());
query.addQueryParameter("market", market);
query.addQueryParameter("returnType", returnType);
query.addQueryParameter("returnCreationDateTo", DateUtils.addDays(returnCreationDateTo, 1));
query.addQueryParameter("returnCreationDateFrom", returnCreationDateFrom);
SearchResult<ReturnRequestModel> results = search(query);
same flow is running properly in local but giving issues in remote instace.
here is error
ERROR PaymentWsController de.hybris.platform.servicelayer.search.exceptions.FlexibleSearchException: could not translate value expression 'session.currentCountry'
19:37:31.834 [hybrisHTTP6] ERROR de.hybris.platform.jalo.flexiblesearch.FlexibleSearch - Flexible search error occured...
This error coming from research restriction. It looks your user hasn't got some session variables and a restriction try to use it. You can check this question answer.
The issue is that you have a SearchRestriction, Search Restriction is a set of rules which is applied on Flexible Search Query in order to limit the search results or to filter search results based on specific conditions.
You can see SearchRestrictions in Backoffice -> System -> Personalization, find the related one that adds session.currentCountry to your flexible search and either disable it or use impersonationService to execute your query inside a context with a site.
Hope this helps
Although others answers on the post are correct I just want to add my answer which helped to solve the issue.
The issue was with search restriction.
I just set current user as admin to bypass the restrictions. i.e.
userService.setCurrentUser(userService.getAdminUser());
I just added it before executing the search and error got resolved.
we can also set user as admin in flexiquery itself so that search restrictions can be avoided.
here is how.
query.setUser(userService.getAdminUser());
so both ways it can be done.

Java retrieve alternative Ldap Attribute names

The situation:
I'm actually reading contact information from an Ldap source within a Java application. The found SearchResult contains all values I want, no trouble with that.
Once the SearchResult is available, I need to read its attributes - which attributes to read, is specified by the user in a config file.
The problem, explained on an example:
A user specifies to read the property 'stateOrProvinceName'. The Ldap handles this as 'st'. The returned Searchresult will contain a key=>value pair with 'st' as key. If I look up 'stateOrProvinceName' this will of cource not be found. I want that 'st' key - but I do not want to manually code a mappnig of alternative Ldap-Field names. The relevant code part:
Attributes ldapAttributes = foundContact.getAttributes();
Attribute wantedAttribute = ldapAttributes.get(ldapFieldName);
Explanation: 'foundContact' is the SearchResult, I store its Attributes in 'ldapAttributes'. The 'ldapFieldName' is the name, the user specified in the config file (like 'stateOrProvinceName'), I try to get this attribute and store it in 'wantedAttribute'. If 'stateOrProvinceName' is not contained, 'wantedAttribute' is of course null. But since 'st' exists, I do not want this to be null ;)
The question:
is there some 'easy' way to retrieve a list of all alternative names, given one name of an attribute?
Thanks for your time!
The rfc'ed approach for that is to locate the attribute definition in your entry's subschemaSubentry referenced schema definition. (p32 in RFC 4512)
E.g. OpenLDAP stores this information in cn=Subschema. Unfortunately this entry uses the attribute definition format which you first have to parse by yourself:
attributetype ( 2.5.4.8
NAME ( 'st' 'stateOrProvinceName' )
DESC 'RFC2256: state or province which this object resides in'
SUP name )
Iirc/maybe UnboundID's LDAP SDK has now a parser for this purspose.

Glassfish 3.1.2 JDBCRealm configuration

Hi I have read Glassfish 3.1.2's JDBCRealm has a new Password Encryption Algorithm field. What is it for? and googled for similar topics but it seems no definitive answer has been published.
In short, I have a jdbc realm working in glassfish 3, when I upgrade to 3.1.2, same configuration does not work. According to the previous thread, I have set the JaasContext to jdbcDigestRealm (in addition to jdbcRealm which also does not work), set the Digest Algorithm to MD5 (I used MD5 in v 3 and it worked). For Password Encryption Algorithm I tried 'blank', and 'hex', both do not work.
Could someone please tell me how I should configure. My credentials table is based on mysql with MD5 hashed passwords according to http://jugojava.blogspot.hk/2011/02/jdbc-security-realm-with-glassfish-and.html.
I succeed to make it works with the following settings. I add a few comments with my current (mis)understanding.
JAASContext = "jdbcRealm" => The value must be set according to file 'glassfish3/glassfish/domains/domain1/config/login.conf'. By default, the class 'com.sun.enterprise.security.auth.login.JDBCLoginModule' (which implement the JDBCrealm) is configured under "jdbcRealm". There is another login module configured under "jdbcDigestRealm". This one is not part of the current topic.
JNDI = "..." => I put there the name of a datasource that already
exists for the database of my application.
UserTable = "MY_SCHEMA.usertable" => The 'full qualified name' of the
database table.
UserNameColumn = "userid" => column name where you store the user
name
PasswordColumn = "password" => column name where you store the (hash
of the) user passsword.
GroupTable = "MY_SCHEMA.grouptable" => The 'full qualified name' of
the database table.
GroupTableUserNameColumn = "" => no clue about the usage of this...
GroupNameColumn = "groupid" => column name where you store the user
name
AssignGroups = "" => As far as I understand the GF code, this is a way to assign a list of groups to every user registered in the realm. It's kind of hard-coding. More or less every realm available on GlassFish (could) make use of this property.
DatabaseUser = "" => As I understood, you need this if you aren't
using the JNDI (the second parameter).
DatabasePassword = "" => As I understood, you need this if you aren't
using the JNDI (the second parameter).
DigestAlgorithm = "SHA-256" => 'MD5', 'SHA-1' or 'SHA-256'. 'SHA-256'
is the default. Let's take 'SHA-256'.
PasswordEncryptionAlgorithm = "AES" => The digest algorithm is applied to the password before storing the password. The new password encryption is an added layer of security which allows the "hash" (the string after the DA has been applied to the password) to be encrypted. In this way, if an attacker retrieves the passwords from the database they are encrypted and hashed. It's highly unlikely that such data would be useful to an attacker.
Encoding = "Hex" => You have the choice between 'Hex' or 'Base64'.
Hex was convenient for me.
Charset = "" => As my database does not have an 'exotic' charset, I
do not think I need to set something smart there. I leave it blank
and it works.
Hope it will help.
PS: If somebody have a link to REAL documentation (not the official one which is completly useless at this moment), please, put a link here.
I spent a while today playing with this (Java EE 7, Glassfish 4 on Ubuntu 12.04). As it turns out, most of the fields on the Realm Page are not needed. The following fields were the only ones that are needed to establish a successful connection to the database.
Realm Name - Any name, as long as you use the same name in web.xml
JAAS Context - Any Name
JNDI - Any Name (I used jdbc/DB Name)
User Table - Table which contains all the users
User Name column - Column in the users table which contains your user-names
Password - Column which contains hashed passwords (SHA 256)
Group Table - Table which contains groups
Group Name Column - Column in the groups table which contain group names
I left everything else blank. My database password column had the password hashed using SHA 256.
I tested this by filling in random text in the 'Password Encryption' field and saving it. Redeployed my application and restarted Glassfish 4. Still worked. This means that the field, while still present is not being read anymore.
P.S - The real documentation as mentioned in the first answer is still quite poor.
First things first. What is your log output?
What are the symptoms of your "not working problem"?
Did basic-authentication pop-up window occurred?
Did you get
No login module configured for jdbcDigestRealm
or other error message?
change security log level if don't have any log output from unsuccessful login attempt.
I have two variations to the jdbcRealm issue. The first existed from a domain that was created using GF 3.1.1 which continued to work after updating the GF server to the 3.1.2.2 release. I then created a new domain on this server. The new domain was configured using the jdbcRealm. All of the parameters were the same for the 3.1.1 configuration except for the "Password Encryption Algorithm" which didn't exist under the 3.1.1 configuration screen. When I tried to login using my Web Application I was constantly getting the "jdbcrealm.invaliduserreason[#]" error in the log file.
The only way that I was able to resolve and to successfully login to my application was by adding the AES to the "Password Encryption Algorithm" field. I saved the change and restarted the server and once again I am able to successfully authenticate users from the jdbcRealm connection.
There is a somewhat more detailed guide here -> http://is.gd/Jx6Gnp

DbUtils QueryRunner with fields of the same name

I swear I've done this before and it's worked fine, but it seems that with the query I have (below) I can't map two columns of the same name (in this case 'email') even when using "as" in my query. I've also tried without the "as" - just having 'u.email assessorEmail' and that query works as well, but with the same problem, the field just doesn't appear in my results when I debug.
getQueryRunner().query("SELECT u.email AS assessorEmail, f.formid, f.firstName, f.surname, f.email, f.valid, f.invalidreason FROM users AS u RIGHT JOIN userforms AS uf ON u.id=uf.user LEFT JOIN forms AS f ON uf.form=f.formid WHERE u.role=? AND f.submitted=1 AND f.valid=0 ORDER BY u.email", new MapListHandler(), Role.ASSESSOR);
MySql result:
assessorEmail formid firstName surname email valid invalidreason
assessor#test.com 547 John Doe user#test.com 0
Eclipse->inspect variable:
[{valid=false, invalidreason=, email=user#test.com, surname=Doe, firstName=John, formid=547}]
If I remove f.email from the query, the u.email appears successfully as 'email' (still not assessorEmail).
Is this a DbUtils thing? A QueryRunner thing? Even a MySql Java connector thing? I'm sure I'm missing something really obvious here...
After a little more digging I found a bug listing for this issue http://bugs.mysql.com/bug.php?id=32504. Seems to be an issue with the connector.
Adding "useOldAliasMetadataBehavior=true" as a parameter to the JDBC URL did the trick.

How can I generically detect if a database is 'empty' from Java

Can anyone suggest a good way of detecting if a database is empty from Java (needs to support at least Microsoft SQL Server, Derby and Oracle)?
By empty I mean in the state it would be if the database were freshly created with a new create database statement, though the check need not be 100% perfect if covers 99% of cases.
My first thought was to do something like this...
tables = metadata.getTables(null, null, null, null);
Boolean isEmpty = !tables.next();
return isEmpty;
...but unfortunately that gives me a bunch of underlying system tables (at least in Microsoft SQL Server).
There are some cross-database SQL-92 schema query standards - mileage for this of course varies according to vendor
SELECT COUNT(*) FROM [INFORMATION_SCHEMA].[TABLES] WHERE [TABLE_TYPE] = <tabletype>
Support for these varies by vendor, as does the content of the columns for the Tables view. SQL implementation of Information Schema docs found here:
http://msdn.microsoft.com/en-us/library/aa933204(SQL.80).aspx
More specifically in SQL Server, sysobjects metadata predates the SQL92 standards initiative.
SELECT COUNT(*) FROM [sysobjects] WHERE [type] = 'U'
Query above returns the count of User tables in the database. More information about the sysobjects table here:
http://msdn.microsoft.com/en-us/library/aa260447(SQL.80).aspx
I don't know if this is a complete solution ... but you can determine if a table is a system table by reading the table_type column of the ResultSet returned by getTables:
int nonSystemTableCount = 0;
tables = metadata.getTables(null, null, null, null);
while( tables.next () ) {
if( !"SYSTEM TABLE".equals( tables.getString( "table_type" ) ) ) {
nonSystemTableCount++;
}
}
boolean isEmpty = nonSystemTableCount == 0;
return isEmpty;
In practice ... I think you might have to work pretty hard to get a really reliable, truly generic solution.
Are you always checking databases created in the same way? If so you might be able to simply select from a subset of tables that you are familiar with to look for data.
You also might need to be concerned about static data perhaps added to a lookup table that looks like 'data' from a cursory glance, but might in fact not really be 'data' in an interesting sense of the term.
Can you provide any more information about the specific problem you are trying to tackle? I wonder if with more data a simpler and more reliable answer might be provided.
Are you creating these databases?
Are you creating them with roughly the same constructor each time?
What kind of process leaves these guys hanging around, and can that constructor destruct?
There is certainly a meta data process to loop through tables, just through something a little more custom might exist.
In Oracle, at least, you can select from USER_TABLES to exclude any system tables.
I could not find a standard generic solution, so each database needs its own tests set.
For Oracle for instance, I used to check tables, sequences and indexes:
select count(*) from user_tables
select count(*) from user_sequences
select count(*) from user_indexes
For SqlServer I used to check tables, views and stored procedures:
SELECT * FROM sys.all_objects where type_desc in ('USER_TABLE', 'SQL_STORED_PROCEDURE', 'VIEW')
The best generic (and intuitive) solution I got, is by using ANT SQL task - all I needed to do is passing different parameters for each type of database.
i.e. The ANT build file looks like this:
<project name="run_sql_query" basedir="." default="main">
<!-- run_sql_query: -->
<target name="run_sql_query">
<echo message="=== running sql query from file ${database.src.file}; check the result in ${database.out.file} ==="/>
<sql classpath="${jdbc.jar.file}"
driver="${database.driver.class}"
url="${database.url}"
userid="${database.user}"
password="${database.password}"
src="${database.src.file}"
output="${database.out.file}"
print="yes"/>
</target>
<!-- Main: -->
<target name="main" depends="run_sql_query"/>
</project>
For more details, please refer to ANT:
https://ant.apache.org/manual/Tasks/sql.html

Categories