Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
MAC_DO(4)		    Kernel Interfaces Manual		     MAC_DO(4)

NAME
       mac_do  -- policy allowing unprivileged users to	change process creden-
       tials

SYNOPSIS
       To compile the mac_do policy into  your	kernel,	 place	the  following
       lines in	your kernel configuration file:

	     options MAC
	     options MAC_DO

       Alternately, to load this policy	module at boot time, place the follow-
       ing line	in your	kernel configuration file:

	     options MAC

       and in loader.conf(5):

	     mac_do_load="YES"

DESCRIPTION
       The  mac_do  policy  module allows unprivileged users to	change process
       credentials according to	rules configured  by  the  administrator.   It
       supports	per-jail configuration.

       Currently,  the mac_do policy module only produces effects to processes
       spawned from the	/usr/bin/mdo executable, please	see  mdo(1)  for  more
       details on this program.

CREDENTIALS RULES
       Rules  specify which transitions	of process credentials mac_do will al-
       low, based on current process credentials and the desired  final	 ones.
       They  are passed	by an administrator in the form	of a string having the
       specific	syntax described below in a top-bottom manner.	They have been
       designed	to be able to finely describe the desired  target  credentials
       in a safe and compact way.

   Top-Level List of Rules
       At  the	top, rules are a possibly empty	list of	individual rules sepa-
       rated by	a semi-colon (`');:
	     <rules>	[<rule>	[`;' <rule>]*]
       They form a disjunction,	i.e., mac_do authorizes	a credentials  transi-
       tion as soon as at least	one rule in the	list matches.

       One  rule is composed of	a <from> part (also called "match") and	a <to>
       part (also called "target"), in this order, separated by	a greater-than
       sign (`>'):
	     <rule>    <from> `>' <to>

   Rule's <from> Part
       The first part of a rule, <from>, is matched against the	credentials of
       the process requesting some credentials transition.  It has the form:
	     <from>    <type> `=' <id>

       <type> must be:
	     <type>    [`uid' |	`gid']
       i.e., one of the	literal	strings	`uid' or `gid'.	 <id> must be the  nu-
       merical	ID  of	a  user	 or  group  and	is matched against the current
       process real ID of the corresponding type, and on type `gid'  addition-
       ally against the	supplementary groups.

   Rule's <to> Part
       The  second  part of a rule, <to>, is a comma-separated (`'), non-empty
       list of target clauses:
	     <to>    <target_clause> [`,' <target_clause>]*
       Target clauses of a given rule also form	a disjunction, i.e.,  the  IDs
       they  specify  are  alternatives	 for the target	credentials, except in
       some cases described below.

       The next	subsections describe the syntax	of  target  clauses,  the  de-
       faults  that  apply and the principle of	non-redundancy and non-contra-
       diction in each rule's <to> part.

   Target Clauses
       A target	clause in a rule's <to>	part must be of	one of	the  following
       forms:
	     <target_clause>	`any'
	     <target_clause>	<flags>	<type> `=' <id>
       The  first form is a compact way	to specify that	any target credentials
       are allowed.  The second	form is	similar	to  that  of  <from>  clauses,
       with the	following extensions:
          <id>	may also be a literal `*' or `any' or `'..  `*'	and `any' both
	   designate  any ID for the specified <type>, and are treated identi-
	   cally.  `'.	designates the process'	current	IDs for	the  specified
	   <type>, as explained	below.
          <flags>  may	 contain  at most one of the `+', `-' and `'!  charac-
	   ters, and may be non-empty only when	<type>	is  `gid'.   Addition-
	   ally, if <id> is `*'	or `any', only the `+' flag may	appear.

       For target clauses of `gid' type, an absence of flag indicates that the
       specified group ID is allowed as	the real, effective and/or saved group
       IDs  (the  "primary"  groups).  Conversely, the presence	of any allowed
       flag indicates that the specification  concerns	supplementary  groups.
       Each flag has a specific	meaning:
          `+'	indicates  that	 the  group  ID	 is allowed as a supplementary
	   group.
          `'!	indicates that the group ID is mandatory,  i.e.,  it  must  be
	   listed in the supplementary groups.
          `-'	indicates  that	the group ID must not be listed	in the supple-
	   mentary groups.
       A  specification	 with  `-'  is	only  useful  in  conjunction  with  a
       `+'-tagged  specification  where	only one of them has `'.  as its <id>.
       Target clauses having the `'!  or `-' flag are "forcing"	 clauses,  and
       as such do not take part	in the disjunction of the other	target clauses
       but rather unconditionally apply	in their rule.

       `'.   is	 a placeholder for IDs that the	calling	process	already	has on
       privilege check.	 For type `uid', it designates	any  of	 the  process'
       real,  effective	or saved user IDs.  For	type `gid', its	effect depends
       on whether flags	are present.  If none is present, it designates	any of
       the process' real, effective or saved group IDs.	 If one	is present, it
       designates any of the process' supplementary groups.

   Defaults for	the <to> Part
       If the <to> part	does not list a	target clause with type	`uid', any  of
       the  current  user  IDs	of  the	calling	process	is accepted.  In other
       words, in this case, mac_do behaves as if a target clause of:
	     uid=.
       had been	listed.

       Similarly, if the <to> part does	not list a  target  clause  with  type
       `gid',  all  the	 groups	 of  the calling process are assumed to	be re-
       quired.	More precisely,	each of	the desired real, effective and	 saved
       group IDs must be one of	the current real, effective or saved group ID,
       and  all	 supplementary	groups must be the same	as those that are cur-
       rent.  It is as if the  <to>  part  had	contained  the	following  two
       clauses:
	     gid=.,!gid=.

   Non-Redundancy and Non-Contradiction	in a <to> Part
       No two target clauses of	a single rule may express the exact same logi-
       cal intent nor contradictory ones.

       In  practice,  no  two clauses may display the same ID except for group
       IDs but only if,	each time the same ID appears, it does so with a  dif-
       ferent  flag, or	no flags only once.  Additionally, the specified flags
       in multiple occurences must not be  contradictory.   For	 example,  the
       same  group  ID appearing with both `+' and `-' will cause rejection of
       the rule.

   Parsing Specifics
       Any amount of whitespace	is allowed around tokens of the	above grammar,
       except that there may be	no spaces between <flags> and <id>  in	target
       clauses.

       For  convenience,  numerical IDs	may be specified as negative integers,
       which are then converted	to unsigned ones as specified in the  C	 stan-
       dard  for the uid_t and gid_t types, which are both 64-bit unsigned in-
       tegers.

RUNTIME	CONFIGURATION
       The following sysctl(8) knobs are available:

       security.mac.do.enabled
	       Enable the mac_do policy.  (Default: 1).

       security.mac.do.rules
	       The list	of credential rules, whose syntax is described in  the
	       "CREDENTIALS  RULES"  section  above.  This list	is specific to
	       each jail.  Please see the "JAIL	 SUPPORT"  section  below  for
	       more details on the interaction of mac_do with jails.

       security.mac.do.print_parse_error
	       Logs  a	message	 on  trying  to	 set  incorrect	 rules via the
	       security.mac.do.rules sysctl(8) knob.

JAIL SUPPORT
       mac_do supports per-jail	configuration of rules.

       By default, at creation,	a new jail has no  credentials	rules,	effec-
       tively disabling	mac_do for its processes.

       The following jail parameters are defined:

       mac.do  Possible	values are:
	       `enable'	  mac_do will enforce specific credential rules	in the
			  jail.	  The mac.do.rules jail	parameter must also be
			  set in this case.
	       `disable'  Disables mac_do in the jail.	Strictly equivalent to
			  jail creation's default behavior and to setting  the
			  rules	to an empty string.
	       `inherit'  The  jail's credentials rules	are inherited from the
			  jail's  parent  (which  may  themselves  have	  been
			  inherited).	Modified  rules	propagate to all chil-
			  dren jails configured	for inheritance.

       mac.do.rules
	       The credentials rules for the jail.  It is always equal to  the
	       value   that   can   be	 retrieved   by	  the  sysctl(8)  knob
	       security.mac.do.rules	described    in	   section    "RUNTIME
	       CONFIGURATION".	 If  set, and the jail parameter mac.do	is not
	       so  explicitly,	the  value  of	the  latter  will  default  to
	       `disable' if empty, else	to `enable'.

       Each jail must have mdo(1) installed at path /usr/bin/mdo, as this path
       is currently not	configurable.

EXAMPLES
       Here  are  several examples of single rules matching processes having a
       real user ID of 10001:

       uid=10001>uid=10002
	       Allows the process to switch all	 of  its  real,	 effective  or
	       saved  user  ID	to 10002, but keeping the groups it is already
	       in, and with the	same primary/supplementary groups split.

       uid=10001>uid=10002,uid=10003
	       Same as the first example, but also allows  to  switch  to  UID
	       10003  instead  of  10002, or possibly having both in different
	       user IDs.

       uid=10001>uid=10002,gid=10002
	       Same as the first example, but the new primary groups  must  be
	       set to 10002 and	no supplementary groups	should be set.

       uid=10001>uid=10002,gid=10002,+gid=.
	       Same  as	 the previous example, but in addition allowing	to re-
	       tain any	current	supplementary groups.

       uid=10001>uid=10002,gid=10002,!gid=.
	       Same as the previous example,  but  with	 the  additional  con-
	       straint that all	current	supplementary groups must be kept.

       uid=10001>uid=10002,gid=10002,+gid=.,-gid=10001
	       Same as `uid=10001>uid=10002,gid=10002,+gid=.' above, but 10001
	       cannot be retained as a supplementary group.

       uid=10001>uid=10002,gid=10002,+gid=.,!gid=10003
	       Same  as	`uid=10001>uid=10002,gid=10002,+gid=.' above, with the
	       additional constraint that 10003	must appear in the  supplemen-
	       tary groups.

       uid=10001>uid=10002,gid=*,+gid=*
	       Same  as	 the  first  example,  but  lifting any	constraints on
	       groups, allowing	the process to become part of  any  groups  it
	       sees fit.

       Here  are  several  examples  of	single rules matching processes	having
       10001 as	their real group IDs or	in their supplementary groups:

       gid=10001>uid=0
	       Makes 10001 a more powerful `wheel' group, allowing its members
	       to switch to root without password.

       gid=10001>gid=10002
	       Allows the process to enter GID 10002 as	a primary  group,  but
	       only if giving up all its supplementary groups.

       gid=10001>gid=10002,+gid=.
	       Same  as	the previous example, but allows to retain any current
	       supplementary groups.

       gid=10001>gid=10002,!gid=.
	       Same as the previous example,  but  with	 the  additional  con-
	       straint that all	current	supplementary groups must be kept.

SEE ALSO
       mdo(1), setcred(2), mac(4), jail(8), sysctl(8)

AUTHORS
       Olivier Certner <olce@FreeBSD.org>
       Baptiste	Daroussin <bapt@FreeBSD.org>

BUGS
       Currently,  mac_do  considers  only  credentials	 transitions requested
       through the setcred(2) system call.  This system	call was in large part
       created so that mac_do can see whole credentials	transitions to	decide
       whether	to  authorize them, which the traditional UNIX's piecewise ap-
       proach of successively changing different parts of them cannot allow.

       However,	calls to traditional or	 standard  credentials-changing	 func-
       tions  can be considered	as full	transitions on their own, however lim-
       ited, and as such should	be equally monitored by	mac_do.	  Future  work
       will lift this restriction.

SECURITY CONSIDERATIONS
       The  threat model for mac_do is to consider userland programs as	gener-
       ally untrustable	to decide upon which credentials changes  are  accept-
       able.   It  is in contrast with the traditional UNIX way	to change cre-
       dentials, in which specialized programs are installed with  the	setuid
       bit,  giving them full administrator privileges so that they are	effec-
       tively able to establish	new ones.   Vulnerabilities  in	 such  creden-
       tials-changing  programs	 can have catastrophic consequences on the in-
       tegrity of the system.

       Consequently, mac_do does not rely on companion	userland  programs  to
       decide  whether some credentials	transition is acceptable.  Instead, it
       maintains its own configuration independently from the  userland	 pass-
       word  and  group	 databases.  Establishing this configuration currently
       itself relies on	 userland  programs  issuing  calls  to	 sysctl(3)  or
       jail(2).	 It should thus	be established near system boot	or jail	start,
       before  any  possible  attacks  could happen on the system, and further
       measures	should be taken	to ensure that potential corruptions does  not
       affect  the configuration in subsequent restarts, such as re-establish-
       ing pristine state or ensuring that the boot procedure up to  the  con-
       figuration of mac_do can	be trusted.

FreeBSD	15.0			 June 11, 2025			     MAC_DO(4)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=mac_do&manpath=FreeBSD+15.0-RELEASE+and+Ports>

home | help