001/*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020package org.apache.hadoop.hbase.security;
021
022import java.io.IOException;
023import java.util.Collection;
024import java.util.HashSet;
025import java.util.Set;
026
027import org.apache.hadoop.conf.Configuration;
028import org.apache.hadoop.hbase.AuthUtil;
029import org.apache.yetus.audience.InterfaceAudience;
030import org.slf4j.Logger;
031import org.slf4j.LoggerFactory;
032
033/**
034 * Keeps lists of superusers and super groups loaded from HBase configuration,
035 * checks if certain user is regarded as superuser.
036 */
037@InterfaceAudience.Private
038public final class Superusers {
039  private static final Logger LOG = LoggerFactory.getLogger(Superusers.class);
040
041  /** Configuration key for superusers */
042  public static final String SUPERUSER_CONF_KEY = "hbase.superuser"; // Not getting a name
043
044  private static Set<String> superUsers;
045  private static Set<String> superGroups;
046  private static User systemUser;
047
048  private Superusers(){}
049
050  /**
051   * Should be called only once to pre-load list of super users and super
052   * groups from Configuration. This operation is idempotent.
053   * @param conf configuration to load users from
054   * @throws IOException if unable to initialize lists of superusers or super groups
055   * @throws IllegalStateException if current user is null
056   */
057  public static void initialize(Configuration conf) throws IOException {
058    superUsers = new HashSet<>();
059    superGroups = new HashSet<>();
060    systemUser = User.getCurrent();
061
062    if (systemUser == null) {
063      throw new IllegalStateException("Unable to obtain the current user, "
064        + "authorization checks for internal operations will not work correctly!");
065    }
066
067    String currentUser = systemUser.getShortName();
068    LOG.trace("Current user name is {}", currentUser);
069    superUsers.add(currentUser);
070
071    String[] superUserList = conf.getStrings(SUPERUSER_CONF_KEY, new String[0]);
072    for (String name : superUserList) {
073      if (AuthUtil.isGroupPrincipal(name)) {
074        superGroups.add(AuthUtil.getGroupName(name));
075      } else {
076        superUsers.add(name);
077      }
078    }
079  }
080
081  /**
082   * @return true if current user is a super user (whether as user running process,
083   * declared as individual superuser or member of supergroup), false otherwise.
084   * @param user to check
085   * @throws IllegalStateException if lists of superusers/super groups
086   *   haven't been initialized properly
087   */
088  public static boolean isSuperUser(User user) {
089    if (superUsers == null) {
090      throw new IllegalStateException("Super users/super groups lists"
091        + " have not been initialized properly.");
092    }
093    if (superUsers.contains(user.getShortName())) {
094      return true;
095    }
096    for (String group : user.getGroupNames()) {
097      if (superGroups.contains(group)) {
098        return true;
099      }
100    }
101    return false;
102  }
103
104  public static Collection<String> getSuperUsers() {
105    return superUsers;
106  }
107
108  public static User getSystemUser() {
109    return systemUser;
110  }
111}