package diskCacheV111.admin ; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.List; import java.util.Map; import dmg.cells.nucleus.CellAdapter; import org.dcache.auth.KAuthFile; import org.dcache.auth.UserAuthBase; import org.dcache.auth.UserAuthRecord; import org.dcache.util.Args; /** * Author : Patrick Fuhrmann, Vladimir Podstavkov * Based on the UserMetaDataProviderExample * */ public class UserMetaDataProviderFnal implements UserMetaDataProvider { private static final Logger _log = LoggerFactory.getLogger(UserMetaDataProviderFnal.class); private final CellAdapter _cell ; private final Map<String,Object> _context; private final Args _args ; private final String _ourName ; private int _requestCount; private final Map<String, Integer> _userStatistics = new HashMap<>(); //generalized kpwd file path used by all flavors private String _kpwdFilePath; /** * We are assumed to provide the following constructor signature. */ public UserMetaDataProviderFnal(CellAdapter cell) { _cell = cell ; _context = _cell.getDomainContext() ; _args = _cell.getArgs() ; _ourName = this.getClass().getName() ; // // // get some information from the // command line or the domain context. // _kpwdFilePath = (String)_context.get("kpwd-file") ; _kpwdFilePath = _kpwdFilePath == null ? _args.getOpt("kpwd-file") : _kpwdFilePath; if (_kpwdFilePath == null) { throw new IllegalArgumentException(_ourName + " : -kpwd-file not specified"); } } /** * just for the fun of it */ public static final String hh_ls = "" ; public String ac_ls( Args args ) { StringBuilder sb = new StringBuilder() ; for (Map.Entry<String, Integer> entry : _userStatistics .entrySet()) { sb.append(entry.getKey()). append(" -> "). append(entry.getValue()). append("\n"); } return sb.toString(); } private void updateStatistics( String userName ) { Integer count = _userStatistics.get(userName); int c = count == null ? 0 : count; _userStatistics.put( userName , c + 1) ; _requestCount++ ; } /** * and of course the interface definition */ @Override public synchronized Map<String,String> getUserMetaData( String userName, String userRole, List<String> attributes ) throws Exception { // // 'attributes' is a list of keys somebody (door) // needs from us. We are assumed to prepare // a map containing the 'key' and the // corresponding values. // we should at least be prepared to know the // 'uid','gid' of the user. // If we are not sure about the user, we should // throw an exception rather returning an empty // map. // updateStatistics( userName ) ; // // get the information for the user // Map<String,String> result = getUserMD(userName, userRole) ; // // check for minimum requirments // if ( ( result.get("uid") == null ) || ( result.get("gid") == null ) || ( result.get("home") == null ) ) { throw new IllegalArgumentException(_ourName + " : insufficient info for user : " + userName + "->" + userRole); } return result; } private Map<String,String> getUserMD(String userPrincipal, String userRole) { KAuthFile authf; UserAuthBase pwdRecord; Map<String, String> answer = new HashMap<>(); int uid, gid; String home; try { authf = new KAuthFile(_kpwdFilePath); } catch ( Exception e ) { _log.warn("User authentication file not found: " + e); return answer; } if (userRole.startsWith("UNSPECIFIED")) { userRole = authf.getIdMapping(userPrincipal); _log.warn("userRole="+userRole); if(userRole == null) { _log.warn("User " + userPrincipal + " not found."); return answer; } } pwdRecord = authf.getUserRecord(userRole); if( pwdRecord == null ) { _log.warn("User " + userRole + " not found."); return answer; } if( !((UserAuthRecord)pwdRecord).hasSecureIdentity(userPrincipal) ) { _log.warn(userPrincipal+": Permission denied"); return answer; } uid = pwdRecord.UID; gid = pwdRecord.GIDs.get(0); home = pwdRecord.Home; answer.put("uid", String.valueOf(uid)); answer.put("gid", String.valueOf(gid)); answer.put("home", home); _log.info("User "+userRole+" logged in"); return answer; } /** * and of course the interface definition */ public String toString() { return "rc="+_requestCount; } }