Privilege Manager for Unix profiles (or roles) define who, what, where, when, and how users are permitted to perform various privileged account actions using variable values in the policy configuration profiles.
Management Console for Unix gives you the ability to centrally manage policy within a graphical user interface. You may view and edit both pmpolicy and sudo policy from the Policy tab on the mangement console.
The following tables list the predefined variables used in profile-based policy.
Profile variable | Value type | Explanation |
---|---|---|
General | ||
pf_profile | String | The profile name. This variable is set by the profileBasedPolicy.conf file to be the base filename of the profile, minus the .profile or .shellprofile extension. |
pf_profiledescription | String |
A description of the profile. EXAMPLE: pf_profiledescription = "This is a description of this profile." |
pf_enableprofile | Boolean |
Set to true to enable the profile. EXAMPLE: pf_enableprofile = true; |
pf_tracelevel | Number |
Enables tracing/debugging output at different levels:
EXAMPLE: pf_tracelevel = 1; |
pf_enablekeystrokelogging | Boolean |
Set to true to enable keystroke logging. EXAMPLE: pf_enablekeystrokelogging = true; |
pf_iologdir | String |
The directory in which to store I/O logs. A unique file is created in this directory for each keystroke logging session. EXAMPLE: pf_iologdir = "/var/opt/quest/qpm4u/iolog/"; |
pf_logpasswords | Boolean |
Set to false to avoid writing passwords to the keystroke log. The password detection is determined by the pf_passprompts list. EXAMPLE: pf_logpasswords = false; |
pf_passprompts | List |
A list of strings interpreted as password prompts in stdout. EXAMPLE: pf_passprompts = {"[pP]assword[ :]*"}; |
Authentication | ||
pf_enableauthentication | Boolean |
Set to true to enable PAM authentication. By default, the submit user is authenticated on the master host using the sshd service. EXAMPLE: pf_enableauthentication = true; |
pf_authenticateonclient | Boolean |
Set to true to require authentication on the client. If set to false, users are authenticated on the server, not on the client. EXAMPLE: pf_authenticateonclient = true; Authentication is only required if pf_enableauthentication = true. |
pf_pamservice | String |
Identifies the PAM service to use when authenticating to PAM. EXAMPLE: pf_pamservice = "sshd"; |
pf_pam_prompt | String |
Configures the prompt to use with PAM. EXAMPLE: pf_pam_prompt = "Password: "; |
pf_allowscp |
|
Set to true to allow scp and non-interactive SSH commands when authentication for the shell is enabled. Only applies to pmksh, pmcsh, pmsh, pmbash, and pmshellwrapper. EXAMPLE: pf_allowscp = false; |
Profile variable | Value type | Explanation |
---|---|---|
Commands | ||
pf_authpaths | List |
Specifies the paths from which commands are permitted to run. Empty lists are ignored. If not empty, this variable is passed to the agent for authorization at the point where the command is about to be run; the agent will then reject a command unless it is run from one of these paths. For a shell profile, this restriction is applied to the shell program itself, and to commands run from within the shell. EXAMPLE: pf_authpaths = { # no path restrictions }; |
pf_authcmds | List |
Commands authorized to run; commands not in the list are rejected. Considerations:
EXAMPLE: pf_authcmds = { "/usr/bin/id *" }; |
pf_enableremotecmds | Boolean |
Set to true to allow commands to run on a different host when running pmrun with the -h option . EXAMPLE: pf_enableremotecmds = false; |
Shell commands | ||
pf_shellcommandsaccept | List |
Specifies the list of commands accepted by pmmasterd when run from within the shell. pmmasterd authorizes listed commands and they produce an event in the audit log. If pf_shellcommandsaccept is not empty, any matching command is accepted; all others are rejected. Considerations:
EXAMPLE: pf_shellcommandsaccept = { }; |
pf_shellcommandsreject | List |
Specifies the list of commands rejected by pmmasterd when run from within the shell. pmmasterd authorizes listed commands and they produce an event in the audit log. If pf_shellcommandsreject is not empty, any matching command is be rejected; all others are accepted. Considerations:
EXAMPLE: pf_shellcommandsreject = { }; |
pf_checkbuiltins | Boolean |
Set to true to use shell builtins just like commands. This only applies to pmksh, pmcsh, and pmsh. EXAMPLE: pf_checkbuiltins = true; |
pf_shellreject | String |
Message to display when a user attempts to run a forbidden command. This only applies to pmksh, pmcsh, pmsh, and pmbash. EXAMPLE: pf_shellreject = "You are not permitted to run this command"; |
Pre-authorized Commands | ||
pf_shellallow | List |
Defines the list of pre-authorized commands allowed by the shell without further authorization by the master. The shell interprets each item in this list as a regular expression. Listed commands do not result in an audit event in the event log. This only applies to pmksh, pmcsh, pmsh, and pmbash. EXAMPLE: pf_shellallow = { "(^|/)(exit|pwd|echo)$", }; |
pf_shellallowpipe | List |
Defines the list of pre-authorized commands allowed by the shell without further authorization by the master, but only in the case where std input is from a pipe (for example, ls | more). The shell interprets each item in this list as a regular expression. Listed commands do not result in an audit event in the eventlog. This only applies to pmksh, pmcsh, pmsh, and pmbash. EXAMPLE: pf_shellallowpipe = { "(^|/)(awk|more|grep)$", # allow pipe to innocuous common commands }; |
pf_shell_forbid |
List |
Defines the list of commands rejected by the shell without further authorization by the master. The shell interprets each item in this list as a regular expression. Listed commands do not result in an audit event in the event log. This only applies to pmksh, pmcsh, pmsh, and pmbash. EXAMPLE: pf_shellforbid = { "(^|/)(passwd|kill|shutdown)$", # forbid sensitive commands "(^|/)(a|b|c|k|z)?sh$", # forbid normal shells "(^|/)(bash|tcsh)$", # forbid normal shells "(^|/)nc$", # forbid cmds that allow remote execution }; |
Profile Variable | Value Type | Explanation |
---|---|---|
Run Hosts | ||
pf_authrunhosts | List |
Hosts where commands can run. If not empty, you can submit commands from any host in this list. EXAMPLES: pf_authsubmithosts = {"host1"}; # allow cmds from host host1 only pf_authsubmithosts = {"*.one.two"}; # allow cmds from *.one.two only pf_authsubmithosts = {ALL}; # allow cmds from all hosts SAFEHOSTS = {"*.one.two"}; pf_authsubmithosts = {SAFEHOSTS}; # allow cmds from *.one.two only |
pf_authrunhostsad | List |
Active Directory host groups where commands can run. If not empty, you can submit commands from any host in this list. You can specify an Active Directory domain name as part of the arguments; for example, as <domain>/<name>, <domain>\\<name>, or <name>. If a domain is not specified, then it uses the default joined domain. These lists do not support wild cards. EXAMPLES: pf_authrunhostsad = { "TESTDOM1/testhosts1", "TESTDOM2/dbhosts1"}; # match any member of either AD group pf_authrunhostsad = { "testhosts1" }; # match members in the specified AD group in the default joined domain pf_authrunhostsad = { }; # match no AD groups |
Submit Hosts | ||
pf_authsubmithosts | List |
Hosts where commands can be submitted. If not empty, you can submit commands from any host in this list. EXAMPLES: pf_authsubmithosts = {"host1"}; # allow cmds from host host1 only pf_authsubmithosts = {"*.one.two"}; # allow cmds from *.one.two only pf_authsubmithosts = {ALL}; # allow cmds from all hosts SAFEHOSTS = {"*.one.two"}; pf_authsubmithosts = {SAFEHOSTS}; # allow cmds from *.one.two only |
pf_authsubmithostsad | List |
Active Directory host groups where commands can be submitted. If not empty, you can submit commands from any host in this list. You can specify a domain name as part of the arguments; for example, as <domain>/<name>, <domain>\\<name>, or <name>. If a domain is not specified, then it uses the default joined domain. These lists do not support wild cards. EXAMPLES: pf_authsubmithostsad = { "TESTDOM1/testhosts1", "TESTDOM2/dbhosts1"}; # match any member of either AD group pf_authsubmithostsad = { "testhosts1" }; # match members in the specified AD group # in the default joined domain pf_authsubmithostsad = { }; # match no AD groups |
Forbidden Run Hosts | ||
pf_forbidrunhosts | List |
Hosts where members are forbidden to run commands. If not empty, you can submit commands from any host NOT in this list. EXAMPLES: pf_forbidrunhosts = {"fred"}; i # allow cmds to all hosts except fred pf_forbidrunhosts = {"*.one.two"}; # allow cmds to all hosts except *.one.two BADHOSTS = {"*.one.two"}; pf_forbidrunhosts = {BADHOSTS}; # allow cmds to all hosts except *.one.two |
pf_forbidrunhostsad | List |
Active Directory host groups where members are forbidden to run commands. If not empty, you can submit commands from any host NOT in this list. You can specify a domain name as part of the arguments; for example, as <domain>/<name>, <domain>\\<name>, or <name>. If a domain is not specified, then it uses the default joined domain. These lists do not support wild cards. EXAMPLES: pf_forbidrunhostsad = { "TESTDOM1/testhosts1", "TESTDOM2/dbhosts1"}; # match any member of either AD group pf_forbidrunhostsad = { "testhosts1" }; # match members in the specified AD group in the default joined domain pf_forbidrunhostsad = { }; # match no AD groups |
Forbidden Submit Hosts | ||
pf_forbidsubmithosts | List |
Hosts where members are forbidden to submit commands. If not empty, you can submit commands from any host NOT in this list. EXAMPLES: pf_forbidsubmithosts = {"host1"}; # allow cmds from all hosts except host1 pf_forbidsubmithosts = {"*.one.two"}; # allow cmds from all hosts except *.one.two BADHOSTS = {"*.one.two"}; pf_forbidsubmithosts = {BADHOSTS}; # allow cmds from all hosts except *.one.two |
pf_forbidrunhostsad |
List |
Active Directory host groups where members are forbidden to submit commands. If not empty, you can submit commands from any host NOT in this list. You can specify a domain name as part of the arguments; for example, as <domain>/<name>, <domain>\\<name>, or <name>. If a domain is not specified, then it uses the default joined domain. These lists do not support wild cards. EXAMPLES: pf_forbidrunhostsad = { "TESTDOM1/testhosts1", "TESTDOM2/dbhosts1"}; # match any member of either AD group pf_forbidrunhostsad = { "testhosts1" }; # match members in the specified AD group in the default joined domain pf_forbidrunhostsad = { }; # match no AD groups |
If a member (a user for the group lists, or a host for the hosts lists) is found in both forbid and auth lists, the request is rejected; the forbid list takes precedence.
Profile variable | Value type | Explanation |
---|---|---|
Users | ||
pf_authusers | List |
Identifies the list of users that match this profile. EXAMPLES: pf_authusers = { }; # No users assigned to this profile pf_authusers = { "jsmith", "dbrown"}; # match either user pf_authusers = { ALL}; # match all users DBUSERS={"TESTDOM1/fred", "TESTDOM2/john"}; # allow cmds from /bin,/usr/bin,/tmp pf_authusers = { "jsmith*", DBUSERS}; # match fred, john & jsmith* |
pf_authuser | String |
Identifies the runas user. EXAMPLE: pf_authuser = user; The runas user can be:
|
Groups | ||
pf_authgroups | List |
You can assign users to this profile by group membership on the client or server host, or by assigning individual user names. By default the group membership is verified against the submit user's group information passed on from the client host by pmrun. You can configure it to verify the group membership on the master host instead, using the pf_useservergroupinfo variable. EXAMPLES: pf_authgroups = { "admins", "dbas"}; # match any member of either group pf_authgroups = { ALL}; # match all groups DBGROUPS = {"db*"}; pf_authgroups = { DBGROUPS, "root"}; # match all db* groups and root |
pf_authgroup | String |
If accepted, the request runs with the specified group as the rungroup. EXAMPLE: pf_authgroup = use_rungroup; The rungroup can be:
|
pf_useservergroupinfo | Boolean |
Set to true to check that the user is a member of one of the pf_authgroups on the master host, otherwise check the user's group membership on the client host. EXAMPLE: pf_useservergroupinfo = false; |
AD Groups | ||
pf_authgroupsad |
List |
Identifies the list of non Unix-enabled AD groups that match this profile. Use the format: <domain>/<name, <domain>\\<name>, or <name>. If you do not specify the domain, it uses the default joined domain. This list does not support wild cards. EXAMPLES: pf_authgroupsad = { "TESTDOM1/testgroup1", "TESTDOM2/dbgroup1"}; # match any member of either AD group pf_authgroupsad = { }; # match no AD groups |
Profile Variable | Value Type | Explanation |
---|---|---|
Time Restrictions | ||
pf_enabletimerestrictions | Boolean |
Set to true to enforce the time restrictions in the restrictionHours list. EXAMPLE: pf_enabletimerestrictions = true; |
pf_restrictionhours | List |
Start and End time of allowed time period. Set to "*" or empty string to disable time restrictions. Use 24-hour format, with no leading zero. EXAMPLES: pf_restrictionhours = {"8:00", "18:00}; # 8am - 8pm pf_restrictionhours = {"22:00", "07:00}; # 10pm - 7am pf_restrictionhours = {"", ""}; # no restrictions pf_restrictionhours = {"*", "*"}; # no restrictions |
pf_restrictiondates | List |
Configures the actual date restrictions applied if pf_enabletimerestrictions is set to true. Specify Start and End dates using yyyy/mm/dd format. EXAMPLES: pf_restrictiondates = {"2012/01/01", ""}; # no expiry pf_restrictiondates = {"", "2012/01/01"}; # no start date pf_restrictiondates = {"2012/01/01", "2012/12/31"}; # check start and end date pf_restrictiondates = {"", ""}; # no restrictions pf_restrictiondates = {"*", "*"}; # no restrictions |
pf_restrictiondow |
List |
Configures the day of the week restrictions applied if pf_enabletimerestrictions is set to true. Specify Days in any order using the lower case 3-letter abbreviation {"fri","sat","sun","mon","tue","wed","thu"}; EXAMPLES: pf_restrictiondow = {"mon","tue","wed","thu","fri"}; # weekdays only pf_restrictiondow = {"fri","sat","sun","mon","tue","wed","thu"}; # all days pf_restrictiondow = {}; # no restrictions |
Profile variable | Value type | Explanation |
---|---|---|
Shell Settings | ||
pf_allowshells | List |
List of allowed shells. Do not specify full paths. This list is not compared with the runcommand, instead it is compared with the special pmshell_prog variable set by a Privilege Manager for Unix shell. Only applies to pmksh, pmcsh, pmsh, pmbash, and pmshellwrapper. EXAMPLE: pf_allowshells ={"pmksh", "pmcsh", "pmsh", "pmshellwrapper"}; |
pf_restricted | Boolean |
Set to true to run the shell in restricted mode. This means:
Only applies to pmksh, pmcsh, pmsh, and pmbash. EXAMPLE: pf_restricted = true; |
pf_shellreadonly | List |
List of environment variables to treat as read-only. In restricted mode, the PATH, ENV, and SHELL variables are always read-only. Only applies to pmksh, pmcsh, pmsh, and pmbash. EXAMPLE: pf_shellreadonly = {}; |
pf_shellcwd | Sting |
Defines the initial directory where the shell program will be run. The default is to use the runuser's home directory. This is particularly relevant for shells running in restricted mode, where the user cannot change the directory. This only applies to pmksh, pmcsh, pmsh, and pmbash. EXAMPLE: pf_shellcwd = use_rundir; |
pf_shellpath |
String |
Defines the PATH that will be applied for the shell session. The default is to set standard paths, and add the runuser's home directory, and the current directory. This is particularly relevant for shells running in restricted mode, where the user cannot change the PATH, and can only run commands relative to the configured PATH. This only applies to pmksh, pmcsh, pmsh, and pmbash. EXAMPLE: pf_shellpath = { "/usr/bin", "/bin", use_rundir, ".", }; |
To understand what happens when the Privilege Manager for Unix policy server receives a request, let's assume the default profile-based policy (pmpolicy) has been configured and user jbloggs issued a pmrun id command from host qpmhost01.
A pmmasterd process on the policy server receives the request, and pmrun sends it details about the request which are recorded as event variables (for example, user="jbloggs", command="id", submithost="qpmhost01", runhost="qpmhost01", date="2013/01/01", time="15:00:00").
With instructions from the code in profileBasedPolicy.conf, pmmasterd looks through each of the profiles until it finds a match between the profile variables (such as, pf_authusers) and the corresponding variables from the request (such as, user).
Note that pmshell and pmshellwrapper requests (such as, pmksh or pmshellwrapper_bash), the code directs pmmasterd to look through the shell profiles instead.
The default profile-based policy (pmpolicy) comes with four profiles: admin, demo, helpdesk, and webadmin.
################################################################################
# Privilege Manager for Unix Profile: demo
#
# This profile permits any user from any host to submit the "id" and "whoami" commands
# to be executed as the root user on the local host.
################################################################################
pf_profiledescription= "Permit root access to id and whoami for demo purposes";
# Enable profile
pf_enableprofile= true;
# Enable Keystroke Logging
pf_enablekeystrokelogging= true;
# No authentication required
pf_enableauthentication= false;
# Apply time restrictions
pf_enabletimerestrictions= true;
# Only permit execution between 7am and 7pm
pf_restrictionhours= {"7:00","19:00"};
# No date restrictions
pf_restrictiondates= {"",""};
# Do not permit user to run remotely using pmrun -h
pf_enableremotecmds= false;
# Run these commands as root user
pf_authuser= "root";
# Run these commands as root's primary group on runhost
pf_authgroup= use_rungroup;
################################################################################
# Profile Membership
################################################################################
# Allow all users to run these commands
pf_authusers={
ALL
};
# allow session to be requested from any host
pf_authsubmithosts={
ALL,
};
# allow session to run on any host
pf_authrunhosts={
ALL,
};
# Only permit commands if run from /usr/bin or /bin
pf_authpaths={
"/usr/bin",
"/bin",
};
# permit id with any number of args (or none)
# permit whoami, only if run with no args
pf_authcmds={
"id **",
"whoami",
};
The demo profile is selected because the who, what, where, and when criteria match the request.
Criteria | Demo Profile Variables | Request Event Variables | Match? |
---|---|---|---|
Who |
pf_authusers={ALL}; |
user="jbloggs" |
Yes |
What |
pf_authcmds= {"id **", "whoami"}; pf_authpaths= {"/usr/bin","/bin"); |
command="id" (n/a, path validated by pmlocald) |
Yes |
Where |
pf_authsubmithosts={ALL}; pf_autrunhosts={ALL}; |
submithost="qpmhost01" runhost="qpmhost01" |
Yes |
Yes |
The policy is not able to validate the command path against pf_authpaths, since an absolute path to the command was not provided with the request. Because of this, pmmasterd accepts the request without checking the path, and leaves pf_authpaths to be validated by the pmlocald.
Once the policy selects a profile, other profile variables may affect how requests are processed. For example, pf_enableauthentication specifies whether password authentication is required.
If the root user issued the same pmrun request, the admin profile would have been selected. Even though both the admin and demo profiles match the request, the admin profile matches first.
The default profile-based policy (pmpolicy) includes a profile_customer_policy.conf file, which you may edit to include customized policy code. This policy file defines the following stub functions and procedures that allow your custom code to run at specific points during the policy evaluation.
fn_customer_init()
This function is called once per policy evaluation, at the start of the policy's main body (located near the end of the profileBasedPolicy.conf file), just after the policy includes the profile_customer_policy.conf file.
fn_custom_profile_init()
This function is called after matching the user or group to a profile (or shell profile) but before checking anything else. You can find the function in procedure pr_processProfile() in the profileBasedPolicy.conf file.
This function can cause the current profile selection to fail by returning a false value.
pr_custom_profile_reset()
Use this procedure to reset custom profile variables added to the profile_customer_policy.conf file. This procedure is called when the profile match fails.
fn_log_and_accept_custom()
This function is called just before the request is accepted, after the request has been successfully matched to a profile. The function is called from the fn_log_and_accept() function in the profileBaseProfile.conf file.
This example demonstrates how to create a new profile variable, pf_forbidusers, that you can use in any profile or shell profile. The customization will cause the profile selection to fail when the user is in the pf_forbidusers list, even if the user matches pf_authusers. This would allow you to blacklist specific users from any profile or shell profile.
The following is an updated profile_customer_policy.conf file indicating the modifications in bold.
############################################################################ # One Identity Privilege Manager for Unix Profile Policy V600 (XXX) # One Identity 2013 # # Sample Default Policy Generated for QPM4U # # This policy is included by file: profileBasedPolicy.conf # # This allows customization at certain points while reading profiles. The # following functions are provided: # - fn_log_and_accept_custom # - fn_custom_profile_init # - pr_custom_profile_reset # - fn_customer_init ############################################################################ # custom profile variables pf_forbidusers={}; ######################################################################### # FUNCTION: fn_log_and_accept_custom # # This function is called by pr_log_and_accept to do any # customer-specific actions required, just before accepting the request. # ######################################################################### function fn_log_and_accept_custom() { return true; } ######################################################################### # FUNCTION: fn_custom_profile_init # Do any custom config required for a profile. # This is called after matching user/group to a profile, # but before checking anything else. ######################################################################### function fn_custom_profile_init() { if (user in pf_forbidusers) return false; return true; } ######################################################################## # PROCEDURE: pr_custom_profile_reset # Reset any custom variables after processing a profile ######################################################################### procedure pr_custom_profile_reset() { #reset these for each profile read pf_forbidusers={}; return; } ######################################################################### # FUNCTION: fn_customer_init # Do any custom config required for the policy # This is called before processing any profiles. ######################################################################### function fn_customer_init() { return true; }
The initial definition of the variable (pf_forbidusers={};) is near the top of the file. In order to be globally accessible, the variable must be defined outside of any function or procedure call. The same statement is also in the pr_custom_profile_reset() procedure so that the variable is reset before a new profile (or shell profile) is read. Finally, some code was added to fn_custom_profile_init() to return false if the user is listed in the variable.
If you add the following to the demo profile, user jbloggs would no longer be able to successfully run pmrun id using that profile:
pf_forbidusers={"jbloggs"};
© 2024 One Identity LLC. ALL RIGHTS RESERVED. Nutzungsbedingungen Datenschutz Cookie Preference Center