You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by de...@apache.org on 2018/08/17 16:29:18 UTC
svn commit: r1838269 - in /uima/uima-ducc/trunk:
src/main/admin/db_access_check.py
uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/utils/HandlersHelper.java
Author: degenaro
Date: Fri Aug 17 16:29:18 2018
New Revision: 1838269
URL: http://svn.apache.org/viewvc?rev=1838269&view=rev
Log:
UIMA-5800 DUCC Web Server (WS) does not honor db.access permissions when changed?
Added:
uima/uima-ducc/trunk/src/main/admin/db_access_check.py (with props)
Modified:
uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/utils/HandlersHelper.java
Added: uima/uima-ducc/trunk/src/main/admin/db_access_check.py
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/src/main/admin/db_access_check.py?rev=1838269&view=auto
==============================================================================
--- uima/uima-ducc/trunk/src/main/admin/db_access_check.py (added)
+++ uima/uima-ducc/trunk/src/main/admin/db_access_check.py Fri Aug 17 16:29:18 2018
@@ -0,0 +1,187 @@
+#!/usr/bin/env python
+# -----------------------------------------------------------------------
+# 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.
+# -----------------------------------------------------------------------
+
+import sys
+
+version_min = [2, 7]
+version_info = sys.version_info
+version_error = False
+if(version_info[0] < version_min[0]):
+ version_error = True
+elif(version_info[0] == version_min[0]):
+ if(version_info[1] < version_min[1]):
+ version_error = True
+if(version_error):
+ print('Python minimum requirement is version '+str(version_min[0])+'.'+str(version_min[1]))
+ sys.exit(1)
+
+import argparse
+import datetime
+import os
+import time
+import traceback
+
+from ducc_util import DuccUtil
+
+# print message
+def output(msg):
+ print msg
+
+# produce a time stamp
+def get_timestamp():
+ tod = time.time()
+ timestamp = datetime.datetime.fromtimestamp(tod).strftime('%Y-%m-%d %H:%M:%S')
+ return timestamp
+
+_flag_debug = False
+
+# record debug message
+def debug(mn,text):
+ if(_flag_debug):
+ type ='D'
+ msg = get_timestamp()+' '+type+' '+mn+' '+text
+ output(msg)
+
+# command to check db access authorization
+
+class AccessCheck(DuccUtil):
+
+ # return method name
+ def _mn(self):
+ return traceback.extract_stack(None,2)[0][2]
+
+ description = 'Determine if LOOKER can view OWNER database data through examination of db.access file in security directory, typically ~/.ducc.'\
+ + ' Return 1 if authorized, 0 otherwise.'\
+ + ' Rules: '\
+ + ' 1. Authorized if OWNER == LOOKER'\
+ + ' or '\
+ + ' 2. Authorized if OWNER db.access file is readable by all'\
+ + ' or '\
+ + ' 3. Authorized if LOOKER groups contains the OWNER db.access file group'\
+ + ''
+
+ def get_args(self):
+ global _flag_debug
+ parser = argparse.ArgumentParser(description=self.description)
+ parser.add_argument('--owner', '-o', action='store', required=True, help='the user who owns the data')
+ parser.add_argument('--looker', '-l', action='store', required=True, help='the user who views the data')
+ parser.add_argument('--debug', '-d', action='store_true', help='display debugging messages')
+ self.args = parser.parse_args()
+ _flag_debug = self.args.debug
+
+ # get property from ducc.properties file
+ def get_ducc_property(self, key):
+ value = self.ducc_properties.get(key)
+ text = 'key:'+key+' '+'value:'+value
+ debug(self._mn(),text)
+
+ # get DUCC security home directory, by default user's $HOME
+ def get_security_home(self):
+ key = 'ducc.security.home'
+ value = self.get_ducc_property(key)
+ if(value == None):
+ home_folder = os.getenv('HOME')
+ value = home_folder.rsplit('/',1)[0]
+ self.ducc_security_home = value
+ text = value
+ debug(self._mn(),text)
+
+ # get db.access file info, comprising file permissions and file group
+ def get_owner_access_data(self):
+ permissions = '----------'
+ group = ''
+ ducc_ling = self.duccling
+ self.get_security_home()
+ security_file = os.path.join(self.ducc_security_home,self.args.owner,'.ducc','db.access')
+ text = 'security_file:'+security_file
+ debug(self._mn(),text)
+ p0 = '-q'
+ p1 = '-u'
+ p2 = self.args.owner
+ p3 = '/usr/bin/stat'
+ p4 = security_file
+ cmd = ducc_ling+' '+p0+' '+p1+' '+p2+' '+p3+' '+p4
+ text = cmd
+ debug(self._mn(),text)
+ lines = self.popen(ducc_ling,p0,p1,p2,p3,p4)
+ for line in lines:
+ line = line.strip()
+ if('Gid' in line):
+ tokens = line.split()
+ permissions = tokens[1].strip('(').strip(')').split('/')[1]
+ group = tokens[8].strip('(').strip(')').split('/')[1]
+ text = 'permissions:'+permissions+' '+'group:'+group
+ return permissions, group
+
+ # get looker's groups
+ def get_looker_groups(self):
+ groups = []
+ ducc_ling = self.duccling
+ p0 = '-q'
+ p1 = '-u'
+ p2 = self.args.owner
+ p3 = '/usr/bin/groups'
+ cmd = ducc_ling+' '+p0+' '+p1+' '+p2+' '+p3
+ text = cmd
+ debug(self._mn(),text)
+ lines = self.popen(ducc_ling,p0,p1,p2,p3)
+ for line in lines:
+ line = line.strip()
+ tokens = line.split()
+ groups = tokens
+ return groups
+
+ # check if looker is authorized to access owner's db info
+ def check_authorization(self):
+ authorized = 0
+ text = 'owner:'+self.args.owner+' '+'looker:'+self.args.looker
+ debug(self._mn(),text)
+ if(self.args.owner == self.args.looker):
+ authorized = 1
+ text = 'authorized:'+str(authorized)+' '+'reason: owner == looker'
+ debug(self._mn(),text)
+ else:
+ file_permissions, file_group = self.get_owner_access_data()
+ text = 'permissions:'+file_permissions+' '+'group:'+file_group
+ debug(self._mn(),text)
+ if(file_permissions[7] == 'r'):
+ authorized = 1
+ text = 'authorized:'+str(authorized)+' '+'reason: owner db.access file readable by all'
+ debug(self._mn(),text)
+ elif(file_permissions[4] == 'r'):
+ looker_groups = self.get_looker_groups()
+ text = 'groups:'+str(looker_groups)
+ debug(self._mn(),text)
+ if(file_group in looker_groups):
+ authorized = 1
+ text = 'authorized:'+str(authorized)+' '+'reason: looker in group assigned to db.access file'
+ debug(self._mn(),text)
+ return authorized
+
+ def main(self, argv):
+ authorized = 0
+ self.get_args()
+ authorized = self.check_authorization()
+ print str(authorized)
+ sys.exit(authorized)
+
+if __name__ == '__main__':
+ instance = AccessCheck()
+ instance.main(sys.argv[1:])
Propchange: uima/uima-ducc/trunk/src/main/admin/db_access_check.py
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: uima/uima-ducc/trunk/src/main/admin/db_access_check.py
------------------------------------------------------------------------------
svn:executable = *
Modified: uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/utils/HandlersHelper.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/utils/HandlersHelper.java?rev=1838269&r1=1838268&r2=1838269&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/utils/HandlersHelper.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/utils/HandlersHelper.java Fri Aug 17 16:29:18 2018
@@ -18,7 +18,11 @@
*/
package org.apache.uima.ducc.ws.utils;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
@@ -237,6 +241,8 @@ public class HandlersHelper {
return retVal;
}
+ private static File devNull = new File("/dev/null");
+
/**
* Look in service owner's security home for db.access file
* and use it's permissions to determine of logged-in user
@@ -245,26 +251,46 @@ public class HandlersHelper {
*/
private static boolean isServiceFileAccessForRead(String reqUser, Properties meta) {
String location = "isServiceFileAccessForRead";
- boolean retVal = false;
- if(reqUser == null) {
- reqUser = System.getProperty("user.name");
- }
- if(reqUser != null) {
- if(meta != null) {
- String svcOwner = meta.getProperty(IServicesRegistry.user);
- if(svcOwner != null) {
- String home = getSecurityHome(svcOwner.trim());
- if(home != null) {
- if(!home.endsWith(File.separator)) {
- home = home+File.separator;
- }
- String path = home+".ducc"+File.separator+"db.access";
- retVal = isFileReadable(reqUser, path);
- if(retVal) {
- duccLogger.debug(location, getDuccId(meta), "user="+reqUser+" "+retVal);
- }
+ boolean retVal= false;
+ String DUCC_HOME = System.getProperty("DUCC_HOME");
+ String duccmon_pwgen = DUCC_HOME+"/admin/db_access_check.py";
+ String owner = meta.getProperty(IServicesRegistry.user);
+ String looker = reqUser;
+ if(looker == null) {
+ duccLogger.debug(location, null, "looker not specified");
+ }
+ else {
+ List<String> cmd = new ArrayList<String>();
+ cmd.add(duccmon_pwgen);
+ cmd.add("--owner");
+ cmd.add(owner);
+ cmd.add("--looker");
+ cmd.add(looker);
+ String cmdline = String.join(" ", cmd);
+ duccLogger.debug(location, null, "cmdline: "+cmdline);
+ ProcessBuilder pb = new ProcessBuilder(cmd);
+ String authorizedCode = "1";
+ try {
+ pb = pb.redirectError(devNull);
+ Process process = pb.start();
+ String line;
+ BufferedReader bri = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ duccLogger.trace(location, null, "read stdout: start");
+ while ((line = bri.readLine()) != null) {
+ duccLogger.debug(location, null, "stdout: "+line);
+ if(line.startsWith(authorizedCode)) {
+ duccLogger.trace(location, null, "authorized!");
+ retVal = true;
}
}
+ bri.close();
+ duccLogger.trace(location, null, "read stdout: end");
+ duccLogger.trace(location, null, "process waitfor: start");
+ process.waitFor();
+ duccLogger.trace(location, null, "process waitfor: end");
+ }
+ catch(Exception e) {
+ duccLogger.error(location, null, e);
}
}
return retVal;