ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/catalina/realm/UserDatabaseRealm.java

Path
ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/catalina/realm/UserDatabaseRealm.java
Status
scanned
Type
file
Name
UserDatabaseRealm.java
Extension
.java
Programming language
Java
Mime type
text/plain
File type
ASCII text, with CRLF line terminators
Tag

      
    
Rootfs path

      
    
Size
11995 (11.7 KB)
MD5
76c3ea109a648b606c54775a1ddebbb4
SHA1
3a3113f95eee0ee20519f69ea81c2b04ce3a4b3a
SHA256
5b42fe07554fb03434b9c9fb0a1bcdc716bef96d072b953055de52f8e063f1fc
SHA512

      
    
SHA1_git
c4e12bb247078f374d4a97b0df4a6352869b0233
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
UserDatabaseRealm.java | 11.7 KB |

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.catalina.realm; import java.io.ObjectStreamException; import java.io.Serial; import java.security.Principal; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import javax.naming.Context; import org.apache.catalina.Group; import org.apache.catalina.LifecycleException; import org.apache.catalina.Role; import org.apache.catalina.Server; import org.apache.catalina.User; import org.apache.catalina.UserDatabase; import org.apache.naming.ContextBindings; import org.apache.tomcat.util.ExceptionUtils; /** * Implementation of {@link org.apache.catalina.Realm} that is based on an implementation of {@link UserDatabase} made * available through the JNDI resources configured for this instance of Catalina. Set the <code>resourceName</code> * parameter to the JNDI resources name for the configured instance of <code>UserDatabase</code> that we should consult. * * @since 4.1 */ public class UserDatabaseRealm extends RealmBase { // ----------------------------------------------------- Instance Variables /** * The <code>UserDatabase</code> we will use to authenticate users and identify associated roles. */ protected volatile UserDatabase database = null; private final Object databaseLock = new Object(); /** * The global JNDI name of the <code>UserDatabase</code> resource we will be utilizing. */ protected String resourceName = "UserDatabase"; /** * Obtain the UserDatabase from the context (rather than global) JNDI. */ private boolean localJndiResource = false; /** * Use a static principal disconnected from the database. This prevents live updates to users and roles having an * effect on authenticated principals, but reduces use of the database. */ private boolean useStaticPrincipal = false; // ------------------------------------------------------------- Properties /** * @return the global JNDI name of the <code>UserDatabase</code> resource we will be using. */ public String getResourceName() { return resourceName; } /** * Set the global JNDI name of the <code>UserDatabase</code> resource we will be using. * * @param resourceName The new global JNDI name */ public void setResourceName(String resourceName) { this.resourceName = resourceName; } /** * @return the useStaticPrincipal flag */ public boolean getUseStaticPrincipal() { return this.useStaticPrincipal; } /** * Allows using a static principal disconnected from the user database. * * @param useStaticPrincipal the new value */ public void setUseStaticPrincipal(boolean useStaticPrincipal) { this.useStaticPrincipal = useStaticPrincipal; } /** * Determines whether this Realm is configured to obtain the associated {@link UserDatabase} from the global JNDI * context or a local (web application) JNDI context. * * @return {@code true} if a local JNDI context will be used, {@code false} if the global JNDI context will be used */ public boolean getLocalJndiResource() { return localJndiResource; } /** * Configure whether this Realm obtains the associated {@link UserDatabase} from the global JNDI context or a local * (web application) JNDI context. * * @param localJndiResource {@code true} to use a local JNDI context, {@code false} to use the global JNDI context */ public void setLocalJndiResource(boolean localJndiResource) { this.localJndiResource = localJndiResource; } // ------------------------------------------------------ Protected Methods /** * Calls {@link UserDatabase#backgroundProcess()}. */ @Override public void backgroundProcess() { UserDatabase database = getUserDatabase(); if (database != null) { database.backgroundProcess(); } } @Override protected String getPassword(String username) { UserDatabase database = getUserDatabase(); if (database == null) { return null; } User user = database.findUser(username); if (user == null) { return null; } return user.getPassword(); } public static String[] getRoles(User user) { Set<String> roles = new HashSet<>(); Iterator<Role> uroles = user.getRoles(); while (uroles.hasNext()) { Role role = uroles.next(); roles.add(role.getName()); } Iterator<Group> groups = user.getGroups(); while (groups.hasNext()) { Group group = groups.next(); uroles = group.getRoles(); while (uroles.hasNext()) { Role role = uroles.next(); roles.add(role.getName()); } } return roles.toArray(new String[0]); } @Override protected Principal getPrincipal(String username) { UserDatabase database = getUserDatabase(); if (database == null) { return null; } User user = database.findUser(username); if (user == null) { return null; } else { if (useStaticPrincipal) { return new GenericPrincipal(username, Arrays.asList(getRoles(user))); } else { return new UserDatabasePrincipal(user, database); } } } /* * Can't do this in startInternal() with local JNDI as the local JNDI context won't be initialised at this point. */ private UserDatabase getUserDatabase() { // DCL so database MUST be volatile if (database == null) { synchronized (databaseLock) { if (database == null) { try { Context context; if (localJndiResource) { context = ContextBindings.getClassLoader(); context = (Context) context.lookup("comp/env"); } else { Server server = getServer(); if (server == null) { containerLog.error(sm.getString("userDatabaseRealm.noNamingContext")); return null; } context = server.getGlobalNamingContext(); } database = (UserDatabase) context.lookup(resourceName); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); if (containerLog != null) { containerLog.error(sm.getString("userDatabaseRealm.lookup", resourceName), t); } database = null; } } } } return database; } // ------------------------------------------------------ Lifecycle Methods @Override protected void startInternal() throws LifecycleException { // If the JNDI resource is global, check it here and fail the context // start if it is not valid. Local JNDI resources can't be validated // this way because the JNDI context isn't available at Realm start. if (!localJndiResource) { UserDatabase database = getUserDatabase(); if (database == null) { throw new LifecycleException(sm.getString("userDatabaseRealm.noDatabase", resourceName)); } } super.startInternal(); } @Override protected void stopInternal() throws LifecycleException { // Perform normal superclass finalization super.stopInternal(); // Release reference to our user database database = null; } @Override public boolean isAvailable() { return database != null && database.isAvailable(); } public static final class UserDatabasePrincipal extends GenericPrincipal { @Serial private static final long serialVersionUID = 1L; private final transient UserDatabase database; public UserDatabasePrincipal(User user, UserDatabase database) { super(user.getName()); this.database = database; } @Override public String[] getRoles() { if (database == null) { return new String[0]; } User user = database.findUser(name); if (user == null) { return new String[0]; } Set<String> roles = new HashSet<>(); Iterator<Role> uroles = user.getRoles(); while (uroles.hasNext()) { Role role = uroles.next(); roles.add(role.getName()); } Iterator<Group> groups = user.getGroups(); while (groups.hasNext()) { Group group = groups.next(); uroles = group.getRoles(); while (uroles.hasNext()) { Role role = uroles.next(); roles.add(role.getName()); } } return roles.toArray(new String[0]); } @Override public boolean hasRole(String role) { if ("*".equals(role)) { return true; } else if (role == null) { return false; } if (database == null) { return super.hasRole(role); } Role dbrole = database.findRole(role); if (dbrole == null) { return false; } User user = database.findUser(name); if (user == null) { return false; } if (user.isInRole(dbrole)) { return true; } Iterator<Group> groups = user.getGroups(); while (groups.hasNext()) { Group group = groups.next(); if (group.isInRole(dbrole)) { return true; } } return false; } /** * Magic method from {@link java.io.Serializable}. * * @return The object to serialize instead of this object * * @throws ObjectStreamException Not thrown by this implementation */ @Serial private Object writeReplace() throws ObjectStreamException { // Replace with a static principal disconnected from the database return new GenericPrincipal(getName(), Arrays.asList(getRoles())); } } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
11.07
Copyrights

      
    
Holders

      
    
Authors

      
    
License detections License expression License expression SPDX
apache_2_0-4bde3f57-78aa-4201-96bf-531cba09e7de apache-2.0 Apache-2.0
URL Start line End line
http://www.apache.org/licenses/LICENSE-2.0 9 9