diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index ae1e22a1bb..7a05f2e12b 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -938,6 +938,9 @@ Release 0.23.3 - UNRELEASED HADOOP-8695. TestPathData fails intermittently with JDK7 (Trevor Robinson via tgraves) + HADOOP-8611. Allow fall-back to the shell-based implementation when + JNI-based users-group mapping fails (Robert Parker via bobby) + Release 0.23.2 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/JniBasedUnixGroupsMappingWithFallback.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/JniBasedUnixGroupsMappingWithFallback.java new file mode 100644 index 0000000000..5b6d538f8a --- /dev/null +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/JniBasedUnixGroupsMappingWithFallback.java @@ -0,0 +1,63 @@ +/** + * 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.hadoop.security; + +import java.io.IOException; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.util.NativeCodeLoader; + +public class JniBasedUnixGroupsMappingWithFallback implements + GroupMappingServiceProvider { + + private static final Log LOG = LogFactory + .getLog(JniBasedUnixGroupsMappingWithFallback.class); + + private GroupMappingServiceProvider impl; + + public JniBasedUnixGroupsMappingWithFallback() { + if (NativeCodeLoader.isNativeCodeLoaded()) { + this.impl = new JniBasedUnixGroupsMapping(); + } else { + LOG.info("Falling back to shell based"); + this.impl = new ShellBasedUnixGroupsMapping(); + } + if (LOG.isDebugEnabled()){ + LOG.debug("Group mapping impl=" + impl.getClass().getName()); + } + } + + @Override + public List getGroups(String user) throws IOException { + return impl.getGroups(user); + } + + @Override + public void cacheGroupsRefresh() throws IOException { + impl.cacheGroupsRefresh(); + } + + @Override + public void cacheGroupsAdd(List groups) throws IOException { + impl.cacheGroupsAdd(groups); + } + +} diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMappingWithFallback.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMappingWithFallback.java new file mode 100644 index 0000000000..7d77c1097b --- /dev/null +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMappingWithFallback.java @@ -0,0 +1,63 @@ +/** + * 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.hadoop.security; + +import java.io.IOException; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.util.NativeCodeLoader; + +public class JniBasedUnixGroupsNetgroupMappingWithFallback implements + GroupMappingServiceProvider { + + private static final Log LOG = LogFactory + .getLog(JniBasedUnixGroupsNetgroupMappingWithFallback.class); + + private GroupMappingServiceProvider impl; + + public JniBasedUnixGroupsNetgroupMappingWithFallback() { + if (NativeCodeLoader.isNativeCodeLoaded()) { + this.impl = new JniBasedUnixGroupsNetgroupMapping(); + } else { + LOG.info("Falling back to shell based"); + this.impl = new ShellBasedUnixGroupsNetgroupMapping(); + } + if (LOG.isDebugEnabled()) { + LOG.debug("Group mapping impl=" + impl.getClass().getName()); + } + } + + @Override + public List getGroups(String user) throws IOException { + return impl.getGroups(user); + } + + @Override + public void cacheGroupsRefresh() throws IOException { + impl.cacheGroupsRefresh(); + } + + @Override + public void cacheGroupsAdd(List groups) throws IOException { + impl.cacheGroupsAdd(groups); + } + +} diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestGroupFallback.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestGroupFallback.java new file mode 100644 index 0000000000..a61eee6409 --- /dev/null +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestGroupFallback.java @@ -0,0 +1,105 @@ +/** + * 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.hadoop.security; + +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.CommonConfigurationKeys; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.junit.Test; + +public class TestGroupFallback { + public static final Log LOG = LogFactory.getLog(TestGroupFallback.class); + + @Test + public void testGroupShell() throws Exception { + Logger.getRootLogger().setLevel(Level.DEBUG); + Configuration conf = new Configuration(); + conf.set(CommonConfigurationKeys.HADOOP_SECURITY_GROUP_MAPPING, + "org.apache.hadoop.security.ShellBasedUnixGroupsMapping"); + + Groups groups = new Groups(conf); + + String username = System.getProperty("user.name"); + List groupList = groups.getGroups(username); + + LOG.info(username + " has GROUPS: " + groupList.toString()); + assertTrue(groupList.size() > 0); + } + + @Test + public void testNetgroupShell() throws Exception { + Logger.getRootLogger().setLevel(Level.DEBUG); + Configuration conf = new Configuration(); + conf.set(CommonConfigurationKeys.HADOOP_SECURITY_GROUP_MAPPING, + "org.apache.hadoop.security.ShellBasedUnixGroupsNetgroupMapping"); + + Groups groups = new Groups(conf); + + String username = System.getProperty("user.name"); + List groupList = groups.getGroups(username); + + LOG.info(username + " has GROUPS: " + groupList.toString()); + assertTrue(groupList.size() > 0); + } + + @Test + public void testGroupWithFallback() throws Exception { + LOG.info("running 'mvn -Pnative -DTestGroupFallback clear test' will " + + "test the normal path and 'mvn -DTestGroupFallback clear test' will" + + " test the fall back functionality"); + Logger.getRootLogger().setLevel(Level.DEBUG); + Configuration conf = new Configuration(); + conf.set(CommonConfigurationKeys.HADOOP_SECURITY_GROUP_MAPPING, + "org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback"); + + Groups groups = new Groups(conf); + + String username = System.getProperty("user.name"); + List groupList = groups.getGroups(username); + + LOG.info(username + " has GROUPS: " + groupList.toString()); + assertTrue(groupList.size() > 0); + } + + @Test + public void testNetgroupWithFallback() throws Exception { + LOG.info("running 'mvn -Pnative -DTestGroupFallback clear test' will " + + "test the normal path and 'mvn -DTestGroupFallback clear test' will" + + " test the fall back functionality"); + Logger.getRootLogger().setLevel(Level.DEBUG); + Configuration conf = new Configuration(); + conf.set(CommonConfigurationKeys.HADOOP_SECURITY_GROUP_MAPPING, + "org.apache.hadoop.security.JniBasedUnixGroupsNetgroupMappingWithFallback"); + + Groups groups = new Groups(conf); + + String username = System.getProperty("user.name"); + List groupList = groups.getGroups(username); + + LOG.info(username + " has GROUPS: " + groupList.toString()); + assertTrue(groupList.size() > 0); + } + +}