diff --git a/src/core/org/apache/hadoop/ipc/Server.java b/src/core/org/apache/hadoop/ipc/Server.java
index 3b7b192..de9a715 100644
--- a/src/core/org/apache/hadoop/ipc/Server.java
+++ b/src/core/org/apache/hadoop/ipc/Server.java
@@ -890,8 +890,9 @@ public abstract class Server {
       }
       
       // TODO: Get the user name from the GSS API for Kerberbos-based security
-      // Create the user subject
-      user = SecurityUtil.getSubject(header.getUgi());
+      // Create the user subject; however use the groups as defined on the
+      // server-side, don't trust the user groups provided by the client
+      user = SecurityUtil.getSubject(header.getUgi().getUserName());
     }
     
     private void processData() throws  IOException, InterruptedException {
diff --git a/src/core/org/apache/hadoop/security/Groups.java b/src/core/org/apache/hadoop/security/Groups.java
new file mode 100644
index 0000000..91998ce
--- /dev/null
+++ b/src/core/org/apache/hadoop/security/Groups.java
@@ -0,0 +1,25 @@
+/**
+ * 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;
+
+public abstract class Groups {
+  abstract List<String> getGroups(String user) throws IOException;
+}
diff --git a/src/core/org/apache/hadoop/security/SecurityUtil.java b/src/core/org/apache/hadoop/security/SecurityUtil.java
index 94b6825..7a4a0e8 100644
--- a/src/core/org/apache/hadoop/security/SecurityUtil.java
+++ b/src/core/org/apache/hadoop/security/SecurityUtil.java
@@ -17,9 +17,11 @@
  */
 package org.apache.hadoop.security;
 
+import java.io.IOException;
 import java.security.Policy;
 import java.security.Principal;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
 
@@ -41,6 +43,8 @@ public class SecurityUtil {
                                    PolicyProvider.DEFAULT_POLICY_PROVIDER));
   }
   
+  private static Groups GROUPS = new UnixGroups();
+  
   /**
    * Set the global security policy for Hadoop.
    * 
@@ -87,6 +91,39 @@ public class SecurityUtil {
   }
   
   /**
+   * Get the {@link Subject} for the user identified by <code>userName</code>.
+   * @param userName user name
+   * @return the {@link Subject} for the user identified by <code>userName</code>
+   * @throws IOException
+   */
+  public static Subject getSubject(String userName) throws IOException {
+    if (userName == null) {
+      return null;
+    }
+    
+    Set<Principal> principals = new HashSet<Principal>();
+    User userPrincipal = new User(userName); 
+    principals.add(userPrincipal);
+    
+    // Get user's groups
+    List<String> groups = GROUPS.getGroups(userName);
+    for (String group : groups) {
+      Group groupPrincipal = new Group(group);
+      principals.add(groupPrincipal);
+    }
+    
+    // Create the ugi with the right groups
+    UserGroupInformation ugi = 
+      new UnixUserGroupInformation(userName, 
+                                   groups.toArray(new String[groups.size()]));
+    principals.add(ugi);
+    Subject user = 
+      new Subject(false, principals, new HashSet<Object>(), new HashSet<Object>());
+    
+    return user;
+  }
+  
+  /**
    * Class representing a configured access control list.
    */
   public static class AccessControlList {
diff --git a/src/core/org/apache/hadoop/security/UnixGroups.java b/src/core/org/apache/hadoop/security/UnixGroups.java
new file mode 100644
index 0000000..efd33d3
--- /dev/null
+++ b/src/core/org/apache/hadoop/security/UnixGroups.java
@@ -0,0 +1,59 @@
+/**
+ * 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.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.hadoop.util.Shell;
+
+public class UnixGroups extends Groups {
+  Map<String, List<String>> userGroups = 
+    new ConcurrentHashMap<String, List<String>>();
+  
+  @Override
+  List<String> getGroups(String user) throws IOException {
+    List<String> groups = userGroups.get(user);
+    if (groups == null) {
+      groups = getUnixGroups(user);
+      userGroups.put(user, groups);
+    }
+    return groups;
+  }
+
+  /** 
+   * Get the current user's group list from Unix by running the command 'groups'
+   * 
+   * @param user user name
+   * @return the groups list that the <code>user</code> belongs to
+   * @throws IOException if encounter any error when running the command
+   */
+  private static List<String> getUnixGroups(final String user) throws IOException {
+    String result = Shell.execCommand(Shell.getGROUPS_FOR_USER_COMMAND(user));
+    StringTokenizer tokenizer = new StringTokenizer(result);
+    List<String> groups = new LinkedList<String>();
+    while (tokenizer.hasMoreTokens()) {
+      groups.add(tokenizer.nextToken());
+    }
+    return groups;
+  }
+}
diff --git a/src/core/org/apache/hadoop/util/Shell.java b/src/core/org/apache/hadoop/util/Shell.java
index 2514bbf..8840cee 100644
--- a/src/core/org/apache/hadoop/util/Shell.java
+++ b/src/core/org/apache/hadoop/util/Shell.java
@@ -44,6 +44,10 @@ abstract public class Shell {
   public static String[] getGROUPS_COMMAND() {
     return new String[]{"bash", "-c", "groups"};
   }
+  /** a Unix command to get a given user's groups list */
+  public static String[] getGROUPS_FOR_USER_COMMAND(final String user) {
+    return new String[]{"bash", "-c", "groups " + user};
+  }
   /** a Unix command to set permission */
   public static final String SET_PERMISSION_COMMAND = "chmod";
   /** a Unix command to set owner */
