/** * Returns a pair consisting of a MarshalledObject and attributes to be bound with the stub. * * @param obj The non-null object to store. * @param inAttrs The possible null attributes to store with object. * @return A non-null Result consisting of the MarshalledObject and attributes. */ private static DirStateFactory.Result jrmpObject(Object obj, Attributes inAttrs) throws NamingException { try { Object mobj = new MarshalledObject(obj); Attributes outAttrs = null; Attribute cname = null; Attribute tnames = null; Attribute objectClass = null; if (inAttrs != null) { // Get existing objectclass attribute objectClass = (Attribute) inAttrs.get("objectClass"); if (objectClass == null && !inAttrs.isCaseIgnored()) { // %%% workaround objectClass = (Attribute) inAttrs.get("objectclass"); } // No objectclasses supplied, use "top" to start if (objectClass == null) { objectClass = new BasicAttribute("objectClass", "top"); } else { objectClass = (Attribute) objectClass.clone(); } cname = inAttrs.get(CLASSNAME_ATTRID); tnames = inAttrs.get(CLASSNAMES_ATTRID); outAttrs = (Attributes) inAttrs.clone(); } else { outAttrs = new BasicAttributes(true); objectClass = new BasicAttribute("objectClass", "top"); } if (cname == null) { outAttrs.put(CLASSNAME_ATTRID, obj.getClass().getName()); } if (tnames == null) { Attribute tAttr = LdapCtxFactory.createTypeNameAttr(obj.getClass()); if (tAttr != null) { outAttrs.put(tAttr); } } boolean structural = (objectClass.size() == 0 || (objectClass.size() == 1 && objectClass.contains("top"))); if (structural) { objectClass.add(STRUCTURAL_OCID); } objectClass.add(MARSHALLED_OCID); outAttrs.put(objectClass); return new DirStateFactory.Result(mobj, outAttrs); } catch (java.io.IOException e) { NamingException ne = new NamingException("Cannot create MarshallObject for " + obj); ne.setRootCause(e); throw ne; } }
private LdapContext bind( String principalName, String password, SocketInfo server, Hashtable<String, String> props) throws NamingException { String ldapUrl = (FORCE_LDAPS ? "ldaps://" : "ldap://") + server + '/'; String oldName = Thread.currentThread().getName(); Thread.currentThread().setName("Connecting to " + ldapUrl + " : " + oldName); LOGGER.fine("Connecting to " + ldapUrl); try { props.put(Context.PROVIDER_URL, ldapUrl); props.put("java.naming.ldap.version", "3"); customizeLdapProperties(props); LdapContext context = (LdapContext) LdapCtxFactory.getLdapCtxInstance(ldapUrl, props); if (!FORCE_LDAPS) { // try to upgrade to TLS if we can, but failing to do so isn't fatal // see http://download.oracle.com/javase/jndi/tutorial/ldap/ext/starttls.html try { StartTlsResponse rsp = (StartTlsResponse) context.extendedOperation(new StartTlsRequest()); rsp.negotiate((SSLSocketFactory) TrustAllSocketFactory.getDefault()); LOGGER.fine("Connection upgraded to TLS"); } catch (NamingException e) { LOGGER.log( Level.FINE, "Failed to start TLS. Authentication will be done via plain-text LDAP", e); context.removeFromEnvironment("java.naming.ldap.factory.socket"); } catch (IOException e) { LOGGER.log( Level.FINE, "Failed to start TLS. Authentication will be done via plain-text LDAP", e); context.removeFromEnvironment("java.naming.ldap.factory.socket"); } } if (principalName == null || password == null || password.equals("")) { // anonymous bind. LDAP uses empty password as a signal to anonymous bind (RFC 2829 5.1), // which means it can never be the actual user password. context.addToEnvironment(Context.SECURITY_AUTHENTICATION, "none"); LOGGER.fine("Binding anonymously to " + ldapUrl); } else { // authenticate after upgrading to TLS, so that the credential won't go in clear text context.addToEnvironment(Context.SECURITY_PRINCIPAL, principalName); context.addToEnvironment(Context.SECURITY_CREDENTIALS, password); LOGGER.fine("Binding as " + principalName + " to " + ldapUrl); } // this is supposed to cause the LDAP bind operation with the server, // but I notice that AD may still accept this and yet fail to search later, // when I tried anonymous bind. // if I do specify a wrong credential, this seems to fail. context.reconnect(null); return context; // worked } finally { Thread.currentThread().setName(oldName); } }