PageRenderTime 35ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/src/java/org/apache/hadoop/security/ShellBasedUnixGroupsNetgroupMapping.java

https://github.com/RS1999ent/hadoop-common
Java | 151 lines | 74 code | 14 blank | 63 comment | 9 complexity | bf371039440eb51bcb24d0461dc84e84 MD5 | raw file
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.hadoop.security;
  19. import java.io.IOException;
  20. import java.util.LinkedList;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.Set;
  24. import java.util.HashSet;
  25. import java.util.StringTokenizer;
  26. import java.util.concurrent.ConcurrentHashMap;
  27. import org.apache.hadoop.classification.InterfaceAudience;
  28. import org.apache.hadoop.classification.InterfaceStability;
  29. import org.apache.commons.logging.Log;
  30. import org.apache.commons.logging.LogFactory;
  31. import org.apache.hadoop.util.Shell;
  32. import org.apache.hadoop.util.Shell.ExitCodeException;
  33. import org.apache.hadoop.security.NetgroupCache;
  34. /**
  35. * A simple shell-based implementation of {@link GroupMappingServiceProvider}
  36. * that exec's the <code>groups</code> shell command to fetch the group
  37. * memberships of a given user.
  38. */
  39. @InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
  40. @InterfaceStability.Evolving
  41. public class ShellBasedUnixGroupsNetgroupMapping
  42. extends ShellBasedUnixGroupsMapping {
  43. private static final Log LOG =
  44. LogFactory.getLog(ShellBasedUnixGroupsNetgroupMapping.class);
  45. /**
  46. * Get unix groups (parent) and netgroups for given user
  47. *
  48. * @param user get groups and netgroups for this user
  49. * @return groups and netgroups for user
  50. */
  51. @Override
  52. public List<String> getGroups(String user) throws IOException {
  53. // parent get unix groups
  54. List<String> groups = new LinkedList<String>(super.getGroups(user));
  55. NetgroupCache.getNetgroups(user, groups);
  56. return groups;
  57. }
  58. /**
  59. * Refresh the netgroup cache
  60. */
  61. @Override
  62. public void cacheGroupsRefresh() throws IOException {
  63. List<String> groups = NetgroupCache.getNetgroupNames();
  64. NetgroupCache.clear();
  65. cacheGroupsAdd(groups);
  66. }
  67. /**
  68. * Add a group to cache, only netgroups are cached
  69. *
  70. * @param groups list of group names to add to cache
  71. */
  72. @Override
  73. public void cacheGroupsAdd(List<String> groups) throws IOException {
  74. for(String group: groups) {
  75. if(group.length() == 0) {
  76. // better safe than sorry (should never happen)
  77. } else if(group.charAt(0) == '@') {
  78. if(!NetgroupCache.isCached(group)) {
  79. NetgroupCache.add(group, getUsersForNetgroup(group));
  80. }
  81. } else {
  82. // unix group, not caching
  83. }
  84. }
  85. }
  86. /**
  87. * Gets users for a netgroup
  88. *
  89. * @param netgroup return users for this netgroup
  90. * @return list of users for a given netgroup
  91. */
  92. protected List<String> getUsersForNetgroup(String netgroup)
  93. throws IOException {
  94. List<String> users = new LinkedList<String>();
  95. // returns a string similar to this:
  96. // group ( , user, ) ( domain, user1, host.com )
  97. String usersRaw = execShellGetUserForNetgroup(netgroup);
  98. // get rid of spaces, makes splitting much easier
  99. usersRaw = usersRaw.replaceAll(" +", "");
  100. // remove netgroup name at the beginning of the string
  101. usersRaw = usersRaw.replaceFirst(
  102. netgroup.replaceFirst("@", "") + "[()]+",
  103. "");
  104. // split string into user infos
  105. String[] userInfos = usersRaw.split("[()]+");
  106. for(String userInfo : userInfos) {
  107. // userInfo: xxx,user,yyy (xxx, yyy can be empty strings)
  108. // get rid of everything before first and after last comma
  109. String user = userInfo.replaceFirst("[^,]*,", "");
  110. user = user.replaceFirst(",.*$", "");
  111. // voila! got username!
  112. users.add(user);
  113. }
  114. return users;
  115. }
  116. /**
  117. * Calls shell to get users for a netgroup by calling getent
  118. * netgroup, this is a low level function that just returns string
  119. * that
  120. *
  121. * @param netgroup get users for this netgroup
  122. * @return string of users for a given netgroup in getent netgroups format
  123. */
  124. protected String execShellGetUserForNetgroup(final String netgroup)
  125. throws IOException {
  126. String result = "";
  127. try {
  128. // shell command does not expect '@' at the begining of the group name
  129. result = Shell.execCommand(
  130. Shell.getUsersForNetgroupCommand(netgroup.substring(1)));
  131. } catch (ExitCodeException e) {
  132. // if we didn't get the group - just return empty list;
  133. LOG.warn("error getting users for netgroup " + netgroup, e);
  134. }
  135. return result;
  136. }
  137. }