hadoop-common-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From omal...@apache.org
Subject svn commit: r1077593 - in /hadoop/common/branches/branch-0.20-security-patches: ./ src/core/org/apache/hadoop/security/ src/hdfs/org/apache/hadoop/hdfs/server/namenode/ src/native/ src/native/src/org/apache/hadoop/security/
Date Fri, 04 Mar 2011 04:33:04 GMT
Author: omalley
Date: Fri Mar  4 04:33:04 2011
New Revision: 1077593

URL: http://svn.apache.org/viewvc?rev=1077593&view=rev
Log:
commit 64486412ecf7208467daec3244d87e9d0d6fe97e
Author: Erik Steffl <steffl@yahoo-inc.com>
Date:   Fri Jul 23 12:02:57 2010 -0700

    HADOOP:6864 from https://issues.apache.org/jira/secure/attachment/12450342/HADOOP-6864-0.20.1xx-1.patch
    
    +++ b/YAHOO-CHANGES.txt
    +    HADOOP-6864. Add ability to get netgroups (as returned by getent
    +    netgroup command) using native code (JNI) instead of forking. (Erik Steffl)
    +

Added:
    hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.java
    hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/NetgroupCache.java
    hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c
Removed:
    hadoop/common/branches/branch-0.20-security-patches/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java.orig
Modified:
    hadoop/common/branches/branch-0.20-security-patches/build.xml
    hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/JniBasedUnixGroupsMapping.java
    hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/ShellBasedUnixGroupsNetgroupMapping.java
    hadoop/common/branches/branch-0.20-security-patches/src/native/Makefile.am
    hadoop/common/branches/branch-0.20-security-patches/src/native/Makefile.in

Modified: hadoop/common/branches/branch-0.20-security-patches/build.xml
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/build.xml?rev=1077593&r1=1077592&r2=1077593&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/build.xml (original)
+++ hadoop/common/branches/branch-0.20-security-patches/build.xml Fri Mar  4 04:33:04 2011
@@ -562,6 +562,15 @@
   	  <class name="org.apache.hadoop.security.JniBasedUnixGroupsMapping" />
   	</javah>
 
+  	<javah
+  	  classpath="${build.classes}"
+  	  destdir="${build.native}/src/org/apache/hadoop/security"
+      force="yes"
+  	  verbose="yes"
+  	  >
+  	  <class name="org.apache.hadoop.security.JniBasedUnixGroupsNetgroupMapping" />
+  	</javah>
+
 	<exec dir="${build.native}" executable="sh" failonerror="true">
 	  <env key="OS_NAME" value="${os.name}"/>
 	  <env key="OS_ARCH" value="${os.arch}"/>

Modified: hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/JniBasedUnixGroupsMapping.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/JniBasedUnixGroupsMapping.java?rev=1077593&r1=1077592&r2=1077593&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/JniBasedUnixGroupsMapping.java
(original)
+++ hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/JniBasedUnixGroupsMapping.java
Fri Mar  4 04:33:04 2011
@@ -33,7 +33,8 @@ import org.apache.hadoop.util.NativeCode
  */
 public class JniBasedUnixGroupsMapping implements GroupMappingServiceProvider {
   
-  private static final Log LOG = LogFactory.getLog(ShellBasedUnixGroupsMapping.class);
+  private static final Log LOG = LogFactory.getLog(
+    JniBasedUnixGroupsMapping.class);
   
   native String[] getGroupForUser(String user);
   

Added: hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.java?rev=1077593&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.java
(added)
+++ hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.java
Fri Mar  4 04:33:04 2011
@@ -0,0 +1,104 @@
+/**
+ * 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.Arrays;
+import java.util.List;
+import java.util.LinkedList;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.util.NativeCodeLoader;
+
+import org.apache.hadoop.security.NetgroupCache;
+
+/**
+ * A JNI-based implementation of {@link GroupMappingServiceProvider} 
+ * that invokes libC calls to get the group
+ * memberships of a given user.
+ */
+public class JniBasedUnixGroupsNetgroupMapping
+  extends JniBasedUnixGroupsMapping {
+  
+  private static final Log LOG = LogFactory.getLog(
+    JniBasedUnixGroupsNetgroupMapping.class);
+
+  private static final NetgroupCache netgroupCache = new NetgroupCache();
+
+  native String[] getUsersForNetgroupJNI(String group);
+  
+  /**
+   * Gets unix groups and netgroups for the user.
+   *
+   * It gets all unix groups as returned by id -Gn but it
+   * only returns netgroups that are used in ACLs (there is
+   * no way to get all netgroups for a given user, see
+   * documentation for getent netgroup)
+   */
+  @Override
+  public List<String> getGroups(String user) throws IOException {
+    // parent gets unix groups
+    List<String> groups = new LinkedList<String>(super.getGroups(user));
+    netgroupCache.getNetgroups(user, groups);
+    return groups;
+  }
+
+  @Override
+  public void cacheGroupsRefresh() throws IOException {
+    List<String> groups = netgroupCache.getNetgroupNames();
+    netgroupCache.clear();
+    cacheGroupsAdd(groups);
+  }
+
+  @Override
+  public void cacheGroupsAdd(List<String> groups) throws IOException {
+    for(String group: groups) {
+      if(group.length() == 0) {
+        // better safe than sorry (should never happen)
+      } else if(group.charAt(0) == '@') {
+        if(!netgroupCache.isCached(group)) {
+          netgroupCache.add(group, getUsersForNetgroup(group));
+        }
+      } else {
+        // unix group, not caching
+      }
+    }
+  }
+
+  /**
+   * Calls JNI function to get users for a netgroup, since C functions
+   * are not reentrant we need to make this synchronized (see
+   * documentation for setnetgrent, getnetgrent and endnetgrent)
+   */
+  protected synchronized List<String> getUsersForNetgroup(String netgroup) {
+    String[] users = null;
+    try {
+      // JNI code does not expect '@' at the begining of the group name
+      users = getUsersForNetgroupJNI(netgroup.substring(1));
+    } catch (Exception e) {
+      LOG.warn("Got exception while trying to obtain the users for netgroup ["
+        + netgroup + "] [" + e + "]");
+    }
+    if (users != null && users.length != 0) {
+      return Arrays.asList(users);
+    }
+    return new LinkedList<String>();
+  }
+}

Added: hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/NetgroupCache.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/NetgroupCache.java?rev=1077593&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/NetgroupCache.java
(added)
+++ hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/NetgroupCache.java
Fri Mar  4 04:33:04 2011
@@ -0,0 +1,90 @@
+/**
+ * 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.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * Class that caches the netgroups and inverts group-to-user map
+ * to user-to-group map
+ */
+public class NetgroupCache {
+
+  private static final Log LOG = LogFactory.getLog(NetgroupCache.class);
+
+  private static boolean netgroupToUsersMapUpdated = true;
+  private static Map<String, Set<String>> netgroupToUsersMap =
+    new ConcurrentHashMap<String, Set<String>>();
+
+  private static Map<String, Set<String>> userToNetgroupsMap =
+    new ConcurrentHashMap<String, Set<String>>();
+
+
+  public void getNetgroups(final String user,
+      List<String> groups) {
+    if(netgroupToUsersMapUpdated) {
+      netgroupToUsersMapUpdated = false; // at the beginning to avoid race
+      //update userToNetgroupsMap
+      for(String netgroup : netgroupToUsersMap.keySet()) {
+        for(String netuser : netgroupToUsersMap.get(netgroup)) {
+          // add to userToNetgroupsMap
+          if(!userToNetgroupsMap.containsKey(netuser)) {
+            userToNetgroupsMap.put(netuser, new HashSet<String>());
+          }
+          userToNetgroupsMap.get(netuser).add(netgroup);
+        }
+      }
+    }
+    if(userToNetgroupsMap.containsKey(user)) {
+      for(String netgroup : userToNetgroupsMap.get(user)) {
+        groups.add(netgroup);
+      }
+    }
+  }
+
+  public List<String> getNetgroupNames() {
+    return new LinkedList<String>(netgroupToUsersMap.keySet());
+  }
+
+  public boolean isCached(String group) {
+    return netgroupToUsersMap.containsKey(group);
+  }
+
+  public void clear() {
+    netgroupToUsersMap.clear();
+  }
+
+  public void add(String group, List<String> users) {
+    if(!isCached(group)) {
+      netgroupToUsersMap.put(group, new HashSet<String>());
+      for(String user: users) {
+        netgroupToUsersMap.get(group).add(user);
+      }
+    }
+    netgroupToUsersMapUpdated = true; // at the end to avoid race
+  }
+}

Modified: hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/ShellBasedUnixGroupsNetgroupMapping.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/ShellBasedUnixGroupsNetgroupMapping.java?rev=1077593&r1=1077592&r2=1077593&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/ShellBasedUnixGroupsNetgroupMapping.java
(original)
+++ hadoop/common/branches/branch-0.20-security-patches/src/core/org/apache/hadoop/security/ShellBasedUnixGroupsNetgroupMapping.java
Fri Mar  4 04:33:04 2011
@@ -40,11 +40,11 @@ public class ShellBasedUnixGroupsNetgrou
   
   private static final Log LOG = LogFactory.getLog(ShellBasedUnixGroupsNetgroupMapping.class);
 
-  private static boolean netgroupToUsersMapUpdated = true;
-  private static Map<String, Set<String>> netgroupToUsersMap =
+  protected static boolean netgroupToUsersMapUpdated = true;
+  protected static Map<String, Set<String>> netgroupToUsersMap =
     new ConcurrentHashMap<String, Set<String>>();
 
-  private static Map<String, Set<String>> userToNetgroupsMap =
+  protected static Map<String, Set<String>> userToNetgroupsMap =
     new ConcurrentHashMap<String, Set<String>>();
   
   @Override
@@ -76,7 +76,7 @@ public class ShellBasedUnixGroupsNetgrou
     }
   }
 
-  private void cacheNetgroup(String group) throws IOException {
+  protected void cacheNetgroup(String group) throws IOException {
     if(netgroupToUsersMap.containsKey(group)) {
       return;
     } else {
@@ -123,7 +123,7 @@ public class ShellBasedUnixGroupsNetgrou
     }
   }
 
-  private void getNetgroups(final String user,
+  protected void getNetgroups(final String user,
       List<String> groups) throws IOException {
     if(netgroupToUsersMapUpdated) {
       netgroupToUsersMapUpdated = false; // at the beginning to avoid race
@@ -161,7 +161,9 @@ public class ShellBasedUnixGroupsNetgrou
       throws IOException {
     String result = "";
     try {
-      result = Shell.execCommand(Shell.getUsersForNetgroupCommand(netgroup));
+      // shell command does not expect '@' at the begining of the group name
+      result = Shell.execCommand(
+        Shell.getUsersForNetgroupCommand(netgroup.substring(1)));
     } catch (ExitCodeException e) {
       // if we didn't get the group - just return empty list;
       LOG.warn("error while getting users for netgroup " + netgroup, e);

Modified: hadoop/common/branches/branch-0.20-security-patches/src/native/Makefile.am
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/native/Makefile.am?rev=1077593&r1=1077592&r2=1077593&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/native/Makefile.am (original)
+++ hadoop/common/branches/branch-0.20-security-patches/src/native/Makefile.am Fri Mar  4
04:33:04 2011
@@ -41,7 +41,8 @@ lib_LTLIBRARIES = libhadoop.la
 libhadoop_la_SOURCES = src/org/apache/hadoop/io/compress/zlib/ZlibCompressor.c \
                        src/org/apache/hadoop/io/compress/zlib/ZlibDecompressor.c \
                        src/org/apache/hadoop/security/getGroup.c \
-                       src/org/apache/hadoop/security/JniBasedUnixGroupsMapping.c
+                       src/org/apache/hadoop/security/JniBasedUnixGroupsMapping.c \
+                       src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c
 libhadoop_la_LDFLAGS = -version-info 1:0:0
 libhadoop_la_LIBADD = -ldl -ljvm
 

Modified: hadoop/common/branches/branch-0.20-security-patches/src/native/Makefile.in
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/native/Makefile.in?rev=1077593&r1=1077592&r2=1077593&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/native/Makefile.in (original)
+++ hadoop/common/branches/branch-0.20-security-patches/src/native/Makefile.in Fri Mar  4
04:33:04 2011
@@ -93,7 +93,7 @@ libLTLIBRARIES_INSTALL = $(INSTALL)
 LTLIBRARIES = $(lib_LTLIBRARIES)
 libhadoop_la_DEPENDENCIES =
 am_libhadoop_la_OBJECTS = ZlibCompressor.lo ZlibDecompressor.lo \
-	getGroup.lo JniBasedUnixGroupsMapping.lo
+	getGroup.lo JniBasedUnixGroupsMapping.lo JniBasedUnixGroupsNetgroupMapping.lo
 libhadoop_la_OBJECTS = $(am_libhadoop_la_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
 depcomp = $(SHELL) $(top_srcdir)/config/depcomp
@@ -230,7 +230,8 @@ lib_LTLIBRARIES = libhadoop.la
 libhadoop_la_SOURCES = src/org/apache/hadoop/io/compress/zlib/ZlibCompressor.c \
                        src/org/apache/hadoop/io/compress/zlib/ZlibDecompressor.c \
                        src/org/apache/hadoop/security/getGroup.c \
-                       src/org/apache/hadoop/security/JniBasedUnixGroupsMapping.c
+                       src/org/apache/hadoop/security/JniBasedUnixGroupsMapping.c \
+                       src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c
 
 libhadoop_la_LDFLAGS = -version-info 1:0:0
 libhadoop_la_LIBADD = -ldl -ljvm
@@ -326,6 +327,7 @@ distclean-compile:
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/JniBasedUnixGroupsMapping.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/JniBasedUnixGroupsNetgroupMapping.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ZlibCompressor.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ZlibDecompressor.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getGroup.Plo@am__quote@
@@ -379,6 +381,13 @@ JniBasedUnixGroupsMapping.lo: src/org/ap
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES)
$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o JniBasedUnixGroupsMapping.lo
`test -f 'src/org/apache/hadoop/security/JniBasedUnixGroupsMapping.c' || echo '$(srcdir)/'`src/org/apache/hadoop/security/JniBasedUnixGroupsMapping.c
 
+JniBasedUnixGroupsNetgroupMapping.lo: src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c
+@am__fastdepCC_TRUE@	if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES)
$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT JniBasedUnixGroupsNetgroupMapping.lo
-MD -MP -MF "$(DEPDIR)/JniBasedUnixGroupsNetgroupMapping.Tpo" -c -o JniBasedUnixGroupsNetgroupMapping.lo
`test -f 'src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c' || echo '$(srcdir)/'`src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c;
\
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/JniBasedUnixGroupsNetgroupMapping.Tpo" "$(DEPDIR)/JniBasedUnixGroupsNetgroupMapping.Plo";
else rm -f "$(DEPDIR)/JniBasedUnixGroupsNetgroupMapping.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c'
object='JniBasedUnixGroupsNetgroupMapping.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES)
$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o JniBasedUnixGroupsNetgroupMapping.lo
`test -f 'src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c' || echo '$(srcdir)/'`src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c
+
 mostlyclean-libtool:
 	-rm -f *.lo
 

Added: hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c?rev=1077593&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c
(added)
+++ hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c
Fri Mar  4 04:33:04 2011
@@ -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 <jni.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <grp.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <string.h>
+
+#include <netdb.h>
+
+#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;
+  }
+}



Mime
View raw message