The Metro Federation of Libraries members are Edmonton Public Library (EPL), Ft. Saskatchewan Public Library (FSPL), St. Albert Public Library (SAPL), and Strathcona County Library (SCL). The Metro Federation members share an interest in collaborating to increase access to library collections and programs for our customers across the Metro Edmonton region. The Me Card project was created to reduce barriers in accessing the library collections and diverse programs of the Metro Federation libraries.
The Me Card is a web-based service that allows customers with a library card from an affiliated Metro Federation library to create an account with and access the collections and programs at one or more other affiliated Metro Federation libraries. Interested customers complete a self-service web form to create an account with libraries other than their home library, letting them use their home library card as their library card at any registered library.
Metro is the server that runs on the ILS server and performs the function of negotiating and translating communications between different ILSs. The design is centered around a few simple requests that are initiated by the customer on a website, then translated and sent to the home (host) library, a response is generated, sent back to the website. The website then confirms the transaction is a way that ensures that no identifiable customer information is stored then passes the response on again as another request to the guest library. The guest then creates a new user record in their ILS.
The Metro server supports the following strategies to manage customer registrations.
Stategy | Key Word | Get | Test | Update | Create | Status | Description |
---|---|---|---|---|---|---|---|
SIP2 | sip2 |
Y | Y | N | N | Y | |
outage | outage |
Y | Y | Y | Y | Y | Used for planned outages. |
Symphony native | symphony-api |
N | N | Y | Y | N | Uses SSH. |
Polaris API (PAPI) | polaris-api |
Y | Y | Y | Y | Y | Supports upto version 7.6. |
Polaris SQL | polaris-sql |
Y | Y | Y | Y | Y | Uses raw SQL statements. |
SirsiDynix web services | sirsidynix-api |
Y | Y | Y | Y | Y | Symphony & Horizon |
Horizon native | bimport |
N | N | Y | Y | N | Horizon only. |
- Polaris PAPI ILSes need to rename the
version
key in thepapi.properties
file toapi-version
.
<entry key="version">v1</entry>
<!-- becomes -->
<entry key="api-version">v1</entry>
- A new version of API is available for PAPI that addresses minor issues with birthdates and normalizes datatypes across similar web service calls.MeCard can now optionally switch between
v1
&v2
.
<entry key="api-version">v2</entry>
Added SirsiDynix web services for Symphony and Horizon libraries.
To use it there is a new sdapi.properties
file as seen below which configures the important settings for web services.
NOTE: SirsiDynix web services DTD states that the maximum password length is 25, so environment.properties
must include at least password-max-length
entry, however the other two password settings remain optional.
<!-- Required: 25. -->
<entry key="password-max-length">25</entry>
<!-- Optional, the default is 4. -->
<!-- <entry key="password-min-length">4</entry> -->
<!-- Optional, the default includes most of the ASCII char set. -->
<!-- <entry key="allowed-password-characters">abcd...7890</entry> -->
You can access Symphony & Horizon web services by modifying the environment.properties
files, changing the *-protocol
entries to sirsidynix-api
. See here for details.
A new .env
file is also required to store the staff ID and password which are kept in a .env
file in the ${METRO_HOME}
directory. See example .env
file below (sirsidynix-api
only).
The .env
file contains the staff user ID and password, as well as the staff prompt override code.
# Environment file for MeCard server.
# This file is used for SDapi to store the 'staffPassword'
# however it could be extended to the papi security class
# as well.
# Application settings
STAFF_ID="STAFF_MEMBER"
STAFF_PASSWORD="SuperS3cr3tP@ssw0rd!"
STAFF_PROMPT_OVERRIDE_CODE="XXXX"
Note: the entry sd-originating-app-id
as far as I know, can be any string and is used as a transaction ID in the logs. The x-sirs-clientId
is a web service ID that has permission to register customers.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>
SirsiDynix Web Service settings.
</comment>
<entry key="load-dir">/home/anisbet/MeCard/logs/Customers</entry>
<entry key="client-id">MY_APP_ID</entry>
<entry key="env-file-path">/home/metro/.env</entry>
<entry key="cache-path">/home/metro/.sd_api.cache</entry>
<entry key="base-url">https://ws.sirsidynix.net</entry>
<!-- <entry key="port">443</entry> optional, default 443 -->
<entry key="x-sirs-clientId">ilsws</entry>
<entry key="sd-originating-app-id">MeCard</entry>
<entry key="web-service-version">6.4.0</entry>
<entry key="connection-timeout">10</entry>
<entry key="http-version">2.0</entry>
<entry key="session-token-expire-time">60</entry>
<entry key="debug">true</entry>
<entry key="default-profile">EPL_METRO</entry>
<entry key="default-library">EPLMNA</entry>
<entry key="default-language">ENGLISH</entry>
<entry key="default-standing">OK</entry>
<entry key="default-keep-circ-history">ALLCHARGES</entry>
<entry key="default-access">PUBLIC</entry>
<entry key="default-environment">PUBLIC</entry>
<entry key="use-city-province">false</entry>
</properties>
commons-daemon-1.4.0.jar
replacement update.gson-2.10.1.jar
replacement update.
Java 11 is now end of life, to be replaced by Java 17. If you upgrade please ask for a new version of the MeCard.jar compiled to version 17. To update your system's version of Java do the following.
On Ubuntu 20.04 and above do the following.
sudo apt install openjdk-17-jdk
(oropenjdk-17-jdk-headless
if you wantjavac
which is not required for the Metro server).- At this point you can test the install with
java -version
. If java is still at version '11' or below, use the commandsudo update-alternatives --config java
(andsudo update-alternatives --config javac
if you chose theheadless
install), it will show a number of selections similar to the following.
There are 2 choices for the alternative java (providing /usr/bin/java).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/lib/jvm/java-17-openjdk-amd64/bin/java 1711 auto mode
1 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 manual mode
2 /usr/lib/jvm/java-17-openjdk-amd64/bin/java 1711 manual mode
Press <enter> to keep the current choice[*], or type selection number:
- Test with
java -version
- You need to add the following directory and link. It's a hack carried over from Java 11 installation instructions.
$ sudo mkdir /usr/lib/jvm/java-17-openjdk-amd64/lib/amd64
$ sudo ln -s /usr/lib/jvm/java-17-openjdk-amd64/lib/server /usr/lib/jvm/java-17-openjdk-amd64/lib/amd64/
- Update
service.sh
as follows.
# replace this -> JAVA_HOME=/usr/lib/jvm/default-java
# with the following.
export JAVA_HOME=$(/bin/readlink -ze /usr/bin/javac | xargs -0 dirname -z | xargs -0 dirname)
Note:
When root starts the process it doesn't seem to have access to readlink
so I explicitly path it. If that doesn't work you can add JAVA_HOME
explicitly as follows.
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
- This version requires a new entry in the
message.properties
file that addresses what to send to a customer if they are discovered to be a duplicate account at the guest library.
<entry key="duplicate-user">Hmm, this looks like a duplicate account, please call the Library at 780-459-1530 for assistance</entry>
- Includes a health check function that augments the
GET_STATUS
command. To use it open atelnet
session on the ME Libraries web server, and enter the following.
...
{"code":"GET_STATUS","authorityToken":"[token here]","userId":"","pin":"","customer":"null"}
{"code":"OK","responseMessage":"Linux version: 5.4.0-189-generic arch:amd64, Java: 11.0.23+9-post-Ubuntu-1ubuntu120.04.2, MeCard version: 2.04.01d, User: its, Up time: 20:44:47 up 15:44, 1 user, load average: 0.00, 0.03, 0.05 hours, Last active: 2024-07-24 20:44:47, Log size: 8427 KB, Transactions: 3149, Err size: 5 KB, Host disk: Total: 14 GB, Free: 5 GB, Usable: 5 GB:Services up.","customer":"null"}
...
Note: If there are two MeCard servers running as may be if there is a Test and Production version, the test server's metro.out
and metro.err
files may be reported instead of Production. This is because the a search has to be made of the local FS because their location is specified in service.sh
.
- Made
Text.isLike()
method more flexible when matching strings in property files. For example asip2.properties
entry like<entry "user-not-found">unknown borrower</entry>
now matches the phrase#Unknown borrower barcode - please refer to the circulation desk.
.
- Fixed invalid PIN messaging. When the customer would enter an invalid PIN the mecard server would respond with a message stating the account could not be registered because of a missing email.
- Horizon sites are warned if they don't use password-restriction entries in
environment.properties
. See Version 2.02.00 notes for more information.
- Horizon sites now use the
SitePasswordRestrictions
as do theSIP
class(es). The password-restriction entries inenvironment.properties
remain optional. See Version 2.02.00 notes for more information.
-
Bug fix for Polaris libraries that use
User1
throughUser5
properties. These are now set correctly if the site opts to make them required. They can be set up in the site'sCustomerNormalizer
class. -
Polaris sites can now set password restrictions on inbound customer accounts. All passwords that contravene the restrictions are hashed to strings of digits to a maximum 19 digits long. The hashed PIN is then sent back to the customer in an email from the ME Libraries web site. This is similar to how customer PINs are handled on Horizon.
-
The environment.properties can include any or all of the following additional optional keys.
<!-- Horizon sites would set this to '4'. -->
<entry key="password-max-length">16</entry>
<!-- Horizon sites would leave this set to '4'. -->
<entry key="password-min-length">4</entry>
<!-- this means only allow digits 0-9 in passwords. -->
<entry key="allowed-password-characters">1234567890</entry>
Note The default entries (those not specified) are:
<entry key="password-max-length">256</entry>
<entry key="password-min-length">4</entry>
<entry key="allowed-password-characters">abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]{}|;:'\",.<>/?` </entry>
Note: The space character is the only white space allowed by default.
Note to the developer: To implement this on another ILS or node you will want to make the changes in the sites site.example.ExampleCustomerNormalizer.normalize()
and site.example.ExampleCustomerNormalizer.finalize()
methods.
- MeCard servers now support Polaris web services (PAPI) version 7.x.
- If using PAPI uses the date format (set in the environment properties) to
“yyyy-MM-dd'T'HH:mm:ss”
. - The environment properties file should now have an entry to test if a customer exists. While this is called a protocol, the ME Libraries front end never sends this as a request. Instead it is used internally by the Responder object.
<entry key="exists-protocol">polaris-api</entry> <!-- or sip2 etc -->
- Make sure to add a papi.properties file with the correct configuration. Of
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>
Polaris API settings.
</comment>
<entry key="load-dir">c:\metro</entry>
<entry key="timezone-difference">0</entry>
<entry key="host">https://search.prl.ab.ca</entry>
<entry key="rest-path">/PAPIservice/REST</entry>
<entry key="internal-domain">PRL</entry>
<entry key="staff-access-id">MeLibrary</entry>
<entry key="staff-password">xxxxxxxxxxxx</entry>
<entry key="papi-version">7.1</entry>
<entry key="http-version">2.0</entry>
<entry key="api-user-id">MeLibrary</entry>
<entry key="api-key">xxxxxxxxxxx-xxxxxxxxxx-xxxx-xxxxxxx</entry>
<entry key="version">v1</entry>
<entry key="language-id">1033</entry>
<entry key="app-id">100</entry>
<entry key="org-id">1</entry>
<entry key="patron-branch-id">3</entry>
<entry key="login-branch-id">73</entry>
<entry key="login-user-id">385</entry>
<entry key="login-workstation-id">1</entry>
<entry key="delivery-option-id">2</entry>
<entry key="ereceipt-option-id">2</entry>
<entry key="patron-code-id">7</entry>
<entry key="connection-timeout">10</entry>
<entry key="debug">true</entry>
<entry key="server-type">production</entry> <!-- default: 'sandbox' -->
</properties>
- The message.properties file needs to have the following fields.
<entry key="too-many-tries">Attempt to use the service too often, please try again later.</entry>
- If you are using polaris_sql.properties, this file now must contain additional entries for key stores.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>
SQL connection settings. MY_SQL or SQL_SERVER.
</comment>
<entry key="load-dir">./</entry>
<entry key="connector-type">SQL_SERVER</entry>
<entry key="conformance">Polaris 7.1</entry>
<entry key="host">10.108.1.71</entry>
<entry key="database">Polaris</entry>
<entry key="username">mesip</entry>
<entry key="password">S0m3P@ssW0rD</entry>
<entry key="patron-code-id">7</entry>
<entry key="organization-id">73</entry>
<entry key="creator-id">294</entry>
<entry key="language-id">1</entry>
<entry key="delivery-option-id">2</entry>
<entry key="email-format-id">2</entry>
<entry key="country-id">2</entry>
<entry key="free-text-label">Home</entry> <!-- ignored in 7.1 and above -->
<entry key="address-label-id">3</entry>
<entry key="user-1">Not in the List</entry>
<entry key="user-2">NULL</entry>
<entry key="user-3">null</entry>
<entry key="user-4">(none)</entry>
<entry key="user-5">(none)</entry>
<!-- These are new for MSSQL server 2019 -->
<entry key="encrypt">true</entry>
<entry key="trust-server-certificate">true</entry>
<entry key="integrated-security"></entry>
<entry key="trust-store"></entry>
<entry key="trust-store-password"></entry>
<entry key="host-name-in-certificate"></entry>
</properties>
- Windows Server (2019) is now supported. See Windows installation notes.
-
The environment.properties file now requires the following tag.
<entry key="ils-type">[ILS_TYPE]</entry>
Where ILS_TYPE can be one of the following
UNKNOWN
,SYMPHONY
,HORIZON
,POLARIS
orSIRSI_DYNIX
. -
The sip2.properties file now requires a new entry as follows.
<entry key="user-not-found">[Text from 'AF' field of the sip2 response]</entry> <!-- typically 'User not found' -->
The exact message will depend on your vendor, and can change between versions of the same sip2 server implementation. Use the Perl script
sip2emu.pl
and an invalid user ID and look for the text in the 'AF' fields for the value for this entry. -
The sip2.properties file now requires a new entry as follows.
<entry key="user-pin-invalid">[Text from 'AF' field of the sip2 response]</entry>
<!-- typically 'Invalid user PIN[ for station user]' -->
The exact message will depend on your vendor, and can change between versions of the same
sip2 server implementation. Use the Perl script sip2emu.pl
and a valid user ID but an invalid
PIN, and look for the text in the 'AF' fields for the value for this entry.
-
You can now specify any of *-protocols in the environment.properties file to be 'outage'. For example, you can change the get-protocol from 'sip2' to 'outage', as shown below, if you know your sip2 service is going to be unavailable.
<entry key="get-protocol">outage|sip2|symphony-api|polaris-api|polaris-sql|sirsidynix-api|bimport</entry>
-
The current MeCard server is built to run in Java 11, and is tested using OpenJDK or (JRE).
-
Support for mssql server 2019 is supported. These additional entries are required in the polaris_sql.properties file.
<entry key="encrypt">true|false</entry>
<entry key="trust-server-certificate">true|false</entry>
<entry key="integrated-security">true|false</entry>
<entry key="trust-store">value</entry>
<entry key="trust-store-password">value</entry>
<entry key="host-name-in-certificate">value</entry>
Installing Procrun (prunsrv.exe and prunmgr.exe) The prunsrv.exe is from commons-daemon-1.1.0-bin-windows.zip /amd64 (REF: http://www.apache.org/dist/commons/daemon/binaries/windows/ and StackOverflow at: https://stackoverflow.com/questions/15543053/prunsrv-exe-service-not-starting-up)
The following steps were used at TRAC to install a new MeCard server under Windows server 2019.
- Review any properties file changes. Recent addtions include changes to environment, sip2, polaris_sql, papi, and messages.
- Have a local user account available on the Windows machine with admin privileges.
- Download the (Open)JDK 11 (or JRE) from https://jdk.java.net/java-se-ri/11. You may also download from Oracle, but you may incur licence fees.
- Unpack the zip file in the
c:\metro\Java\java-jdk-17
directory. Tip if you rename the old folder fromjava
tojava_{version#}
then unpack the new zip file to a folder calledjava
, you won't have to change any path-ing variables. - Add a
%JAVA_HOME%=c:\metro\Java\java-jdk-17
to the system environment variables and set it toc:\metro\Java\java-jdk-17
. Note: just include the path to the root of the Java directory. For examplec:\Program Files\java-jdk-17
or what have you. - Add
%JAVA_HOME%\bin
(from step 4) to the%PATH%
system environment variable. - Test by opening a fresh command prompt and typing
java -version
. - The MeCard server runs as a daemon (in Unix). The equivalent in Windows is a service which uses Apache’s Procrun server which you can download here: https://commons.apache.org/proper/commons-daemon/index.html. Information can be found here: https://commons.apache.org/proper/commons-daemon/procrun.html. The current version is commons-daemon-1.3.1-bin-windows.zip. Each version will contain a commons-daemon-x.x.x.jar which must be added to the build in the (NetBeans) IDE to match the version of the prunmgr.exe and prunsrv.exe.
- Download and unpack the latest mecard_Windows.zip file which will include the
MeCard.jar
, lib files, and 64-bitprunsrv.exe
(AKA procrun) andprunmgr.exe
files. - Update your config files, and move them to
c:\Metro directory
(until I can figure out how to pass a switch and string as parameters). - From a powershell ISE window opened in admin mode, with
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
. - Run this command from an Admin PowerShell (ISE).
- If required, tweak the parameters using the prunmgr.exe with:
c:\Metro\windows\prunmgr.exe //ES//Metro
. See section below.
Run c:\metro\windows\prnmgr.exe //ES//Metro
- Display name: Metro
- Description: MeCard Metro Service
- Path to executable: c:\metro\windows\prunsrv.exe //RS//Metro
- Startup type: Automatic
- Log on as: [x] This account: Local Service or NTADMIN/service or browse and find the desired account.
- Password: xxxxxxxxx or whatever it is.
- Confirm password: xxxxxxxxx or whatever it is.
Depending on the account you will need to grant that account full control for log files inc:\metro\logs
.
- Level: info
- Log path: c:\metro\logs
- Log prefix: commons-daemon
- Pid file: c:\metro\logs\pid.txt
- Redirect Stdout: c:\metro\logs\stdout.txt
- Redirect Stderr: c:\metro\logs\stderr.txt
Check that the intial attempt to install the service didn't create any logs inc:\windows\logFiles\Apache
directory.
- Use default (if installed as the default and if not uncheck and set the path to the
%JAVA_HOME%/bin/server/jvm.dll
) - Java Classpath: c:\metro\dist\MeCard.jar
- Class: mecard.MetroService
- Working Path: c:\metro
- Method: start (this may be disabled, if so select
jvm
in the Mode drop-down, enter start in the Method text box, and then return Mode to Java)
- Class: mecard.MetroService
- Working Path: c:\metro
- Method: stop (this may be disabled, if so select
jvm
in the Mode drop-down, enter stop in the Method text box, and then return Mode to Java)
Click apply and Okay, then start Metro
service in Windows Services.
PowerShell Command to Install the Metro (AKA MeCard) Service.
c:\metro\windows\prunsrv.exe //IS//Metro "--Description=MeCard --Jvm=auto --Startup=auto --StartMode=Java --Classpath='c:\metro\dist\MeCard.jar' --StartClass=mecard.MetroService --StartMethod=start --StopMode=Java --StopClass=mecard.MetroService --StopMethod=stop --LogPath='c:\metro\logs' --LogLevel=Info --LogPrefix=metro --StdOutput='c:\metro\logs\Metro-stdout.txt' --StdError='c:\metro\logs\Metro-stderr.txt'"
There are four places to look for information on issues you may be having.
System event logs
c:\Metro\logs\metro-stdout.txt
c:\Metro\logs\metro-stderr.txt
c:\Metro\logs\commons-daemon.YYYY-MM-DD.log
To check the settings and trouble shoot, run:
c:\metro\windows\prunmgr.exe //ES//Metro
and set the configuration manually from the prunmgr.exe.
Andrew to prepare new tarball for installation by editing the MeCard server version number in the Makefile
in the MeCard/
directory on the development VM, then running
ox:~/MeCard/make dist_unix
If the system has Java 11 running, but has MeCard.jar
version is 1.x.xx, you may be able to run the server without updating the libs, which will save you updating jsvc
as well. For Symphony, the minimum libs are commons-daemon-x.xx.xx.jar
, gson-2.2.4.jar
, and commons-cli-1.2.jar
.
- Install
jsvc
withapt-get
. - Install OpenJDK.
- Install make with
apt-get
. - Red Hat dependencies
- A bare Red Hat VM will need to have
jsvc
installed. Here is a list of tool dependencies. - Gnu
GCC
(sudo yum install gcc
). Make
(sudo yum install make
).- Java JDK (not JRE).
- Download
jsvc
src gzipped tarball (at time of writingcommons-daemon-1.2.4-src.tar.gz
) from here. - Install notes are here. To build the jsvc executable, you need to
cd
into thecommons-daemon-1.2.4-src/src/Native/Unix/
directory and follow notes in theINSTALL.txt
file. - The next step requires
$JAVA_HOME
to be known, or better yet set. You can set it with
export JAVA_HOME=$(readlink -ze /usr/bin/javac | xargs -0 dirname -z | xargs -0 dirname)
- Run
./configure
Thejsvc
executable will be created if all goes well. - Run sudo
ln -s /home/user/path/to/jsvc /usr/bin/jsvc
- Test with
jsvc –help #or other jsvc command.
- Create a directory for the MeCard service; something like /home/user/metro which will be referred to as
$METRO_HOME
for the rest of these instructions. - Download the
Metro_x.xx.xx.tar
ball to the VM. - Un-tar the
Metro_x.xx.xx.tar
ball in the$METRO_HOME
directory. - Edit the *.properties files appropriate to your site, and either copy them to
$METRO_HOME
directory or if you like a cleaner install, create and move them to a$METRO_HOME/config
directory. The files in template_config can be your backup. - Edit the
service.sh
script to suit your environment, noting where the*.properties
files can be found. - Edit the
mecard.service
file to suit your environment and follow System Service Installation notes to install and test it. - Ensure the metro user can use password-less access to the ILS. See Setting up SSH for more information.
The metro server MeCard.jar can now be run as a service on Linux as follows.
- Backup your existing
${METRO}/dist/MeCard.jar
, and download the latest jar for your version of Java. There is one for Java 8.x and Java 11.x. Rename theMeCard_vN.jar
toMeCard.jar
. - Edit the
mecard.service
andMakefile
.prod file to suit your environment and save the changes over the oldMakefile
. - Make sure
service.sh
is in the directory you specified as 'WorkingDirectory' in themecard.service
. - Make sure
service.sh
is executable. You can test by running it on the command line. /path/to/service.sh
start and then check for the MeCard as a running process. - Check for, and stop the metro (MeCard) service using make check and make stop. You may need to kill the process if it is running as root. Using systemctl will prevent this from happening in the future.
- System Service Installation
- Sudo Copy the
mecard.service
file to/etc/systemd/system
- If you have an entry in your crontab to restart the service, comment it out.
- Start the service. In Ubuntu use
sudo
, on RedHatsudo su
to a root shell.
systemctl daemon-reload
systemctl enable mecard.service
systemctl start mecard
systemctl status mecard
# If systemctl fails to run with too many restarts try:
systemctl reset-failed
# or add
mecard.service:StartLimitIntervalSec=5 # Secs betwix retries
mecard.service:StartLimitBurst=2 # number of tries
# within StartLimitIntervalSec.
# back on the cmd line
systemctl daemon-reload
systemctl start mecard.service
When the new service is tested and running, remove the commented out crontab
entry from the above step.
You can still use the Makefile
included as well as it now contains the handy shortcuts, but requires admin privileges. It contains another rule; status which shows the output of systemd startup and shutdown messages.
For example, if you need to shutdown the server use the following command.
sudo systemctl stop mecard # or make stop. Both require root
- wrong path to script
- script not executable
- no shebang (first line)
- Shell script saved with Windows line endings
\r\n
which looks like^M
in a text editor like vi(m). - wrong path in shebang or Windows line ending.
- internal files in your script might be missing access permissions.
- SELinux may be preventing execution of the
ExecStart
parameter; check/var/log/audit/audit.log
for messages of the form:
type=AVC msg=audit([...]): avc: denied { execute } or in the output of ausearch -ts recent -m avc -i
You have the wrong WorkingDirectory parameter
On RedHat and CENTOS the setroubleshoot explains in plain English why a script or application was blocked from executing. You can also check the /var/log/audit/audit.log
file. Install with yum install setroubleshoot setools
sealert -a /var/log/audit/audit.log
#Example: grep httpd /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp
See: https://www.serverlab.ca/tutorials/linux/administration-linux/troubleshooting-selinux-centos-red-hat/ for more information on this topic. Feb. 17, 2022.
This page also has good information: https://serverfault.com/questions/1032597/selinux-is-preventing-from-execute-access-on-the-file-centos Feb. 17, 2022.
The SELinux restricts binaries that can be used in ExecStart
to paths that has system_u:object_r:bin_t:s0
attribute set. Typically those are /usr/bin
/usr/sbin
/usr/libexec
/usr/local/bin
directories.
You need to move the script into one of this directories or change selinux policy to allow systemd
to use binaries in the desired location as:
chcon -R -t bin_t /opt/tomcat/bin/
A restorecon will 'unfix' the above better to update the policy e.g.
semanage fcontext -a -t bin_t "/opt/tomcat/bin(/.*)?" restorecon -r -v /opt/tomcat/bin
UPDATE
If java binary is not located in the standard location (custom JVM distribution), then you need to set bin_t label to it as well. For example, it your JVM installed in /opt/java
, then:
semanage fcontext -a -t bin_t "/opt/java/bin(/.*)?" restorecon -r -v /opt/java/bin
NOTICE: systemd ignores JAVA_HOME
environment variable if it's not set in unit file.
You will have to set permissions for logs and Customers and any
[root@azmetro infrastructure]# ls /etc/*release
/etc/os-release /etc/redhat-release /etc/system-release
[root@azmetro infrastructure]# os-release redhat-release system-release
bash: os-release: command not found
[root@azmetro infrastructure]# for i in $(ls /etc/*release); do echo ===$i===; cat $i; done
===/etc/os-release===
NAME="Red Hat Enterprise Linux"
VERSION="8.2 (Ootpa)"
ID="rhel"
ID_LIKE="fedora"
VERSION_ID="8.2"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Red Hat Enterprise Linux 8.2 (Ootpa)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:8.2:GA"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8"
REDHAT_BUGZILLA_PRODUCT_VERSION=8.2
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="8.2"
===/etc/redhat-release===
Red Hat Enterprise Linux release 8.2 (Ootpa)
===/etc/system-release===
Red Hat Enterprise Linux release 8.2 (Ootpa)
- First log in on the MeCard server as the metro user and generate a pair of authentication keys. Do not enter a passphrase.
metro@mecard:~$ ssh-keygen -t rsa
- Generating public/private rsa key pair.
- Enter file in which to save the key (/home/metro/.ssh/id_rsa):
- Enter passphrase (empty for no passphrase):
- Enter same passphrase again:
- Your identification has been saved in /home/metro/.ssh/id_rsa.
- Your public key has been saved in /home/metro/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:7Z/S6vwmiM+1L8pVtGGu+MfUfq3C8J+VgzUxA23tkWg ils@A
The key's randomart image is:
+---[RSA 2048]----+
| .o o|
| E.=.|
| = .=.|
| . + o =|
| S . +. o |
| o.o. + o|
| ...=B o oo|
| .o.=+oO..o+|
| .=o*X=o+o |
+----[SHA256]-----+
Now use ssh to create a directory ~/.ssh
as sirsi on the ILS. (The directory may already exist, which is fine):
metro@mecard:~$ ssh sirsi@ils mkdir -p .ssh
sirsi@ils's password:
Finally append metro's new public key to sirsi@ils:.ssh/authorized_keys
and enter sirsi's password one last time:
metro@mecard:~> cat .ssh/id_rsa.pub | ssh sirsi@ils 'cat >> .ssh/authorized_keys'
sirsi@ils's password:
From now on you can log into the ILS as sirsi from mecard as metro without password:
metro@mecard:~$ ssh sirsi@ils
Note: Depending on your version of SSH you might also have to do the following changes: Put the public key in .ssh/authorized_keys2 Change the permissions of .ssh to 700 Change the permissions of .ssh/authorized_keys2 to 640 SSH Environment The user shells are restricted by default. To let the ssh shell know where the ILS API tools can be found, set up a /home/sirsi/.ssh/environment file with the following. [ -r "/home/sirsi/.bashrc" ] && . "/home/sirsi/.bashrc" This reads the sirsi user’s bashrc and sets the variables from that for the SSH user.
Firewall You may have to open the port on the VM’s firewall like so.
sudo systemctl stop firewalld
sudo firewall-cmd --add-port=2004/tcp
sudo firewall-cmd --runtime-to-permanent
sudo systemctl restart firewalld
- The
<entry key="date-format"></entry>
entry inenvironment.properties
file must be attended to carefully. It refers to the way time is managed by the underlying system that handles dates such as DOB and expiry. Depending on the service protocol used to update and create users the service will be expecting time in a specific format. Here are some examples.- SQL (Polaris) requires
yyyy-MM-dd HH:mm:ss
format. - PAPI timestamp:
yyyy-MM-dd'T'HH:mm:ss
. - Symphony systems (such as EPL, CPL):
yyyy-MM-dd
, which sounds like it should beyyyyMMdd
but may be converted in the MeCard subsystem.
- SQL (Polaris) requires
--- today>2024-00-17 12:00:00
--- expiry>2025-00-17 12:00:00
java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
- Google has flagged the
setup.exe
as malware. The development team has asked for a review of the application, but until that time the exe may have to be sent by other means. February 9, 2022.
- The
-c c:\path\to\configs
switch doesn't seem to work as expected. I have experimented with several different ways of passing the parameters in prunmgr, but none have panned out. To fix just copy your config properties file into the c:\Metro directory. The MeCard server looks there for properties files by default.
- When using Java 11 you may have an issue with jsvc complaining that it can’t find the JVM environment because jsvc can’t find a jvm in
/usr/bin/default-java
. The solution from StackOverflow.
I experienced the issue with jsvc version 1.0.6, which is the one you get if you run apt install jsvc on Ubuntu. To check the version installed run:
apt list --installed
To fix this issue or use a JVM in an arbitrary location in the file system, replace the -home=<jvm_dir>
switch with -XXaltjvm=<jvm_dir>
in the service.sh
that is referenced in mecard.service
as detailed below. Versions of jsvc
after 1.2.0 may not need this fix anymore, but at the time of writing this I have not tested it. (December 17, 2020).
- Update July 29, 2021 - On systems that are using Open-JDK already, changes to
service.sh
is not not necessary if you are migrating to Ubuntu 18.04, but will be required when moving to 20.04. To test, do the following.
/usr/lib/jvm/default-java/bin/java --version
If you get the following you don’t need to adjust service.sh
.
openjdk 11.0.11 2021-04-20
OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.18.04)
OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.18.04, mixed mode, sharing)
If you get something like the following:
-bash: /usr/lib/jvm/default-java/bin/java: No such file or directory
proceed with the following.
$ sudo mkdir /usr/lib/jvm/java-11-openjdk-amd64/lib/amd64
$ sudo ln -s /usr/lib/jvm/java-11-openjdk-amd64/lib/server /usr/lib/jvm/java-11-openjdk-amd64/lib/amd64/
The changes in the service.sh
file are as follows:
# CHANGE: JAVA_HOME=/usr/lib/jvm/default-java
# TO: JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64/lib/amd64
$EXEC -home=$JAVA_HOME -XXaltjvm=$JAVA_HOME -cp $CLASS_PATH -user $USER -outfile $LOG_OUT -errfile $LOG_ERR -pidfile $PID $1 $CLASS $ARGS
Source code can be found on Git. You can find updated scripts and configs mentioned in the above instructions in the Google Drive shared subdirectory under upates/Systemctl folder.
- commons-cli-1.2.jar
- commons-codec-1.8.jar
- commons-daemon-
- 1.3.1.jar for Java 11
- 1.4.0.jar for Java 17 though works with older versions.
- gson-
- 2.2.4.jar
- 2.10.0.jar for server versions above 3.xx.xx.
- mssql-jdbc-10.2.1.jre11.jar. MeCard not tested with newer version (take note TRAC).
- mysql-connector-java-5.1.31-bin.jar
The protocol for metro is a simple request response message system, where each message is a string of pipe-delimited fields. Once a socket is open to a metro service it will acknowlege with a code XK0|
signaling that it is ready for a request, or if there was a socket error on the server you may get a XE0|
. The code XX0|
terminates the session.
As soon as the client contacts a mecard service it will receive an acknowlege
"XX0|" = TERMINATE
"XK0|" = ACKNOWLEDGE
"XE0|" = ERROR
All fields are separated with a delimiter DELIMITER = "|" DEFAULT_FIELD = "X"
Sending receiving requests from Metro requires some knowlege of the communication protocol. The protocol is broken down into two types of activities standard to all network communication: request, or query, and response. Requests are innumerated below:
- "QA0" = GET_STATUS
- "QB0" = GET_CUSTOMER
- "QC0" = CREATE_CUSTOMER
- "QD0" = UPDATE_CUSTOMER
- "QN0" = NULL NULL is a special command type that has no effect.
- "RA9" = ERROR // Command was received but failed to execute either it was malformed, empty (null), or not supported.
- "RA0" = INIT // all responses start in this state, but once the constructor is finished the state changes to BUSY.
- "RA1" = OK // occurs if a query was successful but there is nothing to return, as with get status of the ILS.
- "RA2" = BUSY // Initial working state of a query, testing a response during execution would return this value.
- "RA3" = UNAVAILABLE // occurs if the SIP2 server timesout, or the ILS is unavailable.
- "RA4" = SUCCESS // occurs if the query was successful.
- "RA5" = FAIL // occurs if the request failed, ie: the customer's account couldn't be found.
- "RA6" = UNAUTHORIZED // occurs if the client sends the wrong API key, or if the user id and password don't match.