Return-Path: Delivered-To: apmail-hadoop-common-commits-archive@www.apache.org Received: (qmail 85515 invoked from network); 24 Dec 2010 00:45:30 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 24 Dec 2010 00:45:30 -0000 Received: (qmail 18165 invoked by uid 500); 24 Dec 2010 00:45:30 -0000 Delivered-To: apmail-hadoop-common-commits-archive@hadoop.apache.org Received: (qmail 18140 invoked by uid 500); 24 Dec 2010 00:45:30 -0000 Mailing-List: contact common-commits-help@hadoop.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: common-dev@hadoop.apache.org Delivered-To: mailing list common-commits@hadoop.apache.org Received: (qmail 18133 invoked by uid 99); 24 Dec 2010 00:45:30 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 24 Dec 2010 00:45:29 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 24 Dec 2010 00:45:26 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id E98E923889E7; Fri, 24 Dec 2010 00:45:04 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1052420 [3/3] - in /hadoop/common/trunk: ./ src/java/org/apache/hadoop/security/ src/java/org/apache/hadoop/security/authorize/ src/java/org/apache/hadoop/util/ src/native/ src/native/src/org/apache/hadoop/security/ src/test/core/org/apach... Date: Fri, 24 Dec 2010 00:45:04 -0000 To: common-commits@hadoop.apache.org From: boryas@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20101224004504.E98E923889E7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: hadoop/common/trunk/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c URL: http://svn.apache.org/viewvc/hadoop/common/trunk/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c?rev=1052420&view=auto ============================================================================== --- hadoop/common/trunk/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c (added) +++ hadoop/common/trunk/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c Fri Dec 24 00:45:03 2010 @@ -0,0 +1,138 @@ +/** + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "org_apache_hadoop_security_JniBasedUnixGroupsNetgroupMapping.h" +#include "org_apache_hadoop.h" + +struct listElement { + char * string; + struct listElement * next; +}; + +typedef struct listElement UserList; + +JNIEXPORT jobjectArray JNICALL +Java_org_apache_hadoop_security_JniBasedUnixGroupsNetgroupMapping_getUsersForNetgroupJNI +(JNIEnv *env, jobject jobj, jstring jgroup) { + + // pointers to free at the end + const char *cgroup = NULL; + jobjectArray jusers = NULL; + + // do we need to end the group lookup? + int setnetgrentCalledFlag = 0; + + // if not NULL then THROW exception + char *errorMessage = NULL; + + cgroup = (*env)->GetStringUTFChars(env, jgroup, NULL); + if (cgroup == NULL) { + goto END; + } + + //-------------------------------------------------- + // get users + // see man pages for setnetgrent, getnetgrent and endnetgrent + + UserList *userListHead = NULL; + int userListSize = 0; + + // set the name of the group for subsequent calls to getnetgrent + // note that we want to end group lokup regardless whether setnetgrent + // was successfull or not (as long as it was called we need to call + // endnetgrent) + setnetgrentCalledFlag = 1; + if(setnetgrent(cgroup) == 1) { + UserList *current = NULL; + // three pointers are for host, user, domain, we only care + // about user now + char *p[3]; + while(getnetgrent(p, p + 1, p + 2)) { + if(p[1]) { + current = (UserList *)malloc(sizeof(UserList)); + current->string = malloc(strlen(p[1]) + 1); + strcpy(current->string, p[1]); + current->next = userListHead; + userListHead = current; + userListSize++; + } + } + } + + //-------------------------------------------------- + // build return data (java array) + + jusers = (jobjectArray)(*env)->NewObjectArray(env, + userListSize, + (*env)->FindClass(env, "java/lang/String"), + NULL); + if (jusers == NULL) { + errorMessage = "java/lang/OutOfMemoryError"; + goto END; + } + + UserList * current = NULL; + + // note that the loop iterates over list but also over array (i) + int i = 0; + for(current = userListHead; current != NULL; current = current->next) { + jstring juser = (*env)->NewStringUTF(env, current->string); + if (juser == NULL) { + errorMessage = "java/lang/OutOfMemoryError"; + goto END; + } + (*env)->SetObjectArrayElement(env, jusers, i++, juser); + } + + +END: + + // cleanup + if(cgroup) { (*env)->ReleaseStringUTFChars(env, jgroup, cgroup); } + if(setnetgrentCalledFlag) { endnetgrent(); } + while(userListHead) { + UserList *current = userListHead; + userListHead = userListHead->next; + if(current->string) { free(current->string); } + free(current); + } + + // return results or THROW + if(errorMessage) { + THROW(env, errorMessage, NULL); + return NULL; + } else { + return jusers; + } +} Modified: hadoop/common/trunk/src/test/core/org/apache/hadoop/security/authorize/TestAccessControlList.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/src/test/core/org/apache/hadoop/security/authorize/TestAccessControlList.java?rev=1052420&r1=1052419&r2=1052420&view=diff ============================================================================== --- hadoop/common/trunk/src/test/core/org/apache/hadoop/security/authorize/TestAccessControlList.java (original) +++ hadoop/common/trunk/src/test/core/org/apache/hadoop/security/authorize/TestAccessControlList.java Fri Dec 24 00:45:03 2010 @@ -19,15 +19,152 @@ package org.apache.hadoop.security.autho import java.util.Iterator; import java.util.Set; +import java.util.List; +import org.junit.Test; +import org.junit.Before; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.hadoop.fs.CommonConfigurationKeysPublic; +import org.apache.hadoop.util.NativeCodeLoader; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.security.Groups; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.authorize.AccessControlList; +@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"}) +@InterfaceStability.Evolving +public class TestAccessControlList { -import junit.framework.TestCase; + private static final Log LOG = + LogFactory.getLog(TestAccessControlList.class); -public class TestAccessControlList extends TestCase { - + /** + * Test the netgroups (groups in ACL rules that start with @) + * + * This is a manual test because it requires: + * - host setup + * - native code compiled + * - specify the group mapping class + * + * Host setup: + * + * /etc/nsswitch.conf should have a line like this: + * netgroup: files + * + * /etc/netgroup should be (the whole file): + * lasVegas (,elvis,) + * memphis (,elvis,) (,jerryLeeLewis,) + * + * To run this test: + * + * export JAVA_HOME='path/to/java' + * ant \ + * -Dtestcase=TestAccessControlList \ + * -Dtest.output=yes \ + * -DTestAccessControlListGroupMapping=$className \ + * compile-native test + * + * where $className is one of the classes that provide group + * mapping services, i.e. classes that implement + * GroupMappingServiceProvider interface, at this time: + * - org.apache.hadoop.security.JniBasedUnixGroupsNetgroupMapping + * - org.apache.hadoop.security.ShellBasedUnixGroupsNetgroupMapping + * + */ + @Test + public void testNetgroups() throws Exception { + + if(!NativeCodeLoader.isNativeCodeLoaded()) { + LOG.info("Not testing netgroups, " + + "this test only runs when native code is compiled"); + return; + } + + String groupMappingClassName = + System.getProperty("TestAccessControlListGroupMapping"); + + if(groupMappingClassName == null) { + LOG.info("Not testing netgroups, no group mapping class specified, " + + "use -DTestAccessControlListGroupMapping=$className to specify " + + "group mapping class (must implement GroupMappingServiceProvider " + + "interface and support netgroups)"); + return; + } + + LOG.info("Testing netgroups using: " + groupMappingClassName); + + Configuration conf = new Configuration(); + conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_GROUP_MAPPING, + groupMappingClassName); + + Groups groups = Groups.getUserToGroupsMappingService(conf); + + AccessControlList acl; + + // create these ACLs to populate groups cache + acl = new AccessControlList("ja my"); // plain + acl = new AccessControlList("sinatra ratpack,@lasVegas"); // netgroup + acl = new AccessControlList(" somegroup,@someNetgroup"); // no user + + // this ACL will be used for testing ACLs + acl = new AccessControlList("carlPerkins ratpack,@lasVegas"); + acl.addGroup("@memphis"); + + // validate the netgroups before and after rehresh to make + // sure refresh works correctly + validateNetgroups(groups, acl); + groups.refresh(); + validateNetgroups(groups, acl); + + } + + /** + * Validate the netgroups, both group membership and ACL + * functionality + * + * Note: assumes a specific acl setup done by testNetgroups + * + * @param groups group to user mapping service + * @param acl ACL set up in a specific way, see testNetgroups + */ + private void validateNetgroups(Groups groups, + AccessControlList acl) throws Exception { + + // check that the netgroups are working + List elvisGroups = groups.getGroups("elvis"); + assertTrue(elvisGroups.contains("@lasVegas")); + assertTrue(elvisGroups.contains("@memphis")); + List jerryLeeLewisGroups = groups.getGroups("jerryLeeLewis"); + assertTrue(jerryLeeLewisGroups.contains("@memphis")); + + // allowed becuase his netgroup is in ACL + UserGroupInformation elvis = + UserGroupInformation.createRemoteUser("elvis"); + assertUserAllowed(elvis, acl); + + // allowed because he's in ACL + UserGroupInformation carlPerkins = + UserGroupInformation.createRemoteUser("carlPerkins"); + assertUserAllowed(carlPerkins, acl); + + // not allowed because he's not in ACL and has no netgroups + UserGroupInformation littleRichard = + UserGroupInformation.createRemoteUser("littleRichard"); + assertUserNotAllowed(littleRichard, acl); + } + + @Test public void testWildCardAccessControlList() throws Exception { AccessControlList acl; @@ -46,6 +183,7 @@ public class TestAccessControlList exten // Check if AccessControlList.toString() works as expected. // Also validate if getAclString() for various cases. + @Test public void testAclString() { AccessControlList acl; @@ -83,6 +221,7 @@ public class TestAccessControlList exten new AccessControlList(acl.getAclString()).toString())); } + @Test public void testAccessControlList() throws Exception { AccessControlList acl; Set users; @@ -134,6 +273,7 @@ public class TestAccessControlList exten /** * Test addUser/Group and removeUser/Group api. */ + @Test public void testAddRemoveAPI() { AccessControlList acl; Set users; @@ -196,6 +336,7 @@ public class TestAccessControlList exten /** * Tests adding/removing wild card as the user/group. */ + @Test public void testAddRemoveWildCard() { AccessControlList acl = new AccessControlList("drwho tardis"); @@ -237,6 +378,7 @@ public class TestAccessControlList exten /** * Tests adding user/group to an wild card acl. */ + @Test public void testAddRemoveToWildCardACL() { AccessControlList acl = new AccessControlList(" * "); assertTrue(acl.isAllAllowed()); @@ -266,6 +408,7 @@ public class TestAccessControlList exten /** * Verify the method isUserAllowed() */ + @Test public void testIsUserAllowed() { AccessControlList acl;