skip to content

Per-Command Authorization

Each shell command is sent to the server as AV pairs - service, cmd, cmd-arg, priv-lvl - and comes back passed, added to or replaced. Interviewers drill it as the capability RADIUS lacks.

on this pageshow

questions

6

When a network device asks a TACACS+ server about a typed command, which argument-value pairs carry that command?

level: middleimportance: must knowfreq 52%

answer

  1. one counted list of text pairs
  2. one name, one value, one separator
  3. service is never optional
  4. shell means cmd must be there
  5. cmd-arg repeats, and order matters

basics

~20 s

Three pairs do the work: service names what the authorization is for and MUST always be present, cmd names the command and MUST be present when service=shell, and one repeated, order-dependent cmd-arg carries each word the operator typed after it.

solid answer

~40 s

The authorization REQUEST's variable part is a counted list of argument-value strings, `arg_cnt` of them. For a command line, `service=shell` says what is being authorized and must always be included; `cmd` must be specified whenever `service` is `shell`, and it holds the command name; each subsequent word of the command travels as its own `cmd-arg` pair, and those are **order-dependent**, so the server sees the command as typed. RFC 8907 Section 8.2 lists the rest of the dictionary — `protocol`, `acl`, `inacl`, `outacl`, `addr`, `addr-pool`, `timeout`, `idletime`, `autocmd`, `noescape`, `nohangup`, `priv-lvl` — most of which belong to non-shell services or to what the server returns rather than to what the device asks.

code

pseudocode · 10 lines
pseudocode
AUTHOR REQUEST (seq_no = 1)
  authen_method = TAC_PLUS_AUTHEN_METH_TACACSPLUS   (0x06)
  priv_lvl      = TAC_PLUS_PRIV_LVL_USER            (0x01)
  authen_type   = TAC_PLUS_AUTHEN_TYPE_NOT_SET      (0x00)
  user          = "n.okafor"
  rem_addr      = "198.51.100.24"
  arg_cnt       = 3
    arg_1 = "service=shell"
    arg_2 = "cmd=restart"
    arg_3 = "cmd-arg=routing"

go deeper

for a junior

Learn the three names and what each holds: service for what is being authorized, cmd for the command, cmd-arg for each word after it.

for a middle

Explain the two MUST rules — service always present, cmd present whenever service=shell — and why the repeated cmd-arg pairs are order-dependent.

for a senior

Show you can read a captured argument list and say what was typed, and that you know an empty cmd value changes the request from a command question to a shell question.

for a principal

Consider what a policy language costs when its inputs are ordered text words: rules are written against a vocabulary each device software release may render slightly differently.

## The shape of the REQUEST A TACACS+ authorization REQUEST has a fixed part and a variable part. The fixed part carries `authen_method` (how the device says the user was authenticated), `priv_lvl` (the privilege level the session currently holds), `authen_type`, the user, the port the login arrived on and `rem_addr`. The variable part is what the question is really about: a count, `arg_cnt`, followed by that many **argument-value strings**. Each string is one name and one value joined by a separator. There is no nesting and no typing — everything is text. ## The three that carry a command - **`service`** — what this authorization is for. It **MUST always be included**. For an administrative command line the value is `shell`; the dictionary also defines `tty-server`, `connection`, `system` and `firewall` for other kinds of authorized service. - **`cmd`** — the command name. It **MUST be specified when `service` equals `shell`**. Its value is the first word the operator typed. - **`cmd-arg`** — one pair per remaining word. It is **repeatable and order-dependent**: the server sees them in the order they were typed, which is what allows policy to distinguish a read-only form of a command from a destructive one that differs only in a later word. So an operator on a broadcaster's contribution-circuit routers who types a two-word command produces a REQUEST whose argument list reads `service=shell`, `cmd=<first word>`, `cmd-arg=<second word>` — three arguments, `arg_cnt` of 3. ## The rest of the dictionary RFC 8907 Section 8.2 defines the full set. It is worth knowing which direction each one usually travels, because a candidate who thinks the device sends all of them will describe the exchange backwards. | argument | what it is for | usually sent by | |---|---|---| | `service` | names the service being authorized | the device | | `cmd`, `cmd-arg` | the command and its words | the device | | `protocol` | a protocol within the named service | the device | | `priv-lvl` | a privilege level to assign | the server | | `timeout`, `idletime` | session limits to apply | the server | | `autocmd`, `noescape`, `nohangup` | shell behaviour to impose | the server | | `acl`, `inacl`, `outacl` | access-list identity or content | the server | | `addr`, `addr-pool` | an address, or the pool to draw one from | the server | ## Where the privilege level actually travels This is the trap in the leaf. **`priv_lvl`** with an underscore is a fixed field of the REQUEST body and carries the level the session holds right now. **`priv-lvl`** with a hyphen is an argument-value pair, and it is typically what the *server returns* to set a level for a shell. They are two carriers of the same number pointing in opposite directions, and saying only "the privilege level" in an answer leaves the listener unable to tell which one you mean. ## An empty value is a real value An argument's value may be empty: the argument `cmd` with no value travels as the four characters `cmd=`. That is not a malformed packet, it is a different question. A REQUEST carrying `service=shell` and `cmd=` is a **session-based** authorization — the device is asking to bring up a command line at all, and it will take the returned arguments as the shell's parameters. A REQUEST carrying `service=shell` and a populated `cmd` is a **command-based** authorization about that one command. Both are the same two-packet exchange; only the arguments differ. ## What the device does not put in The REQUEST does not carry a password, a policy name, or any statement about what the device thinks the answer should be. It also carries no result: the command has not run yet, so there is nothing to report about its outcome. And it carries no proof of the identity in it — `authen_method` is the device's own claim about an earlier exchange, not evidence. ## Why this is the middle-tier question A junior can say the device asks the server. The middle-tier answer is the vocabulary: which pairs must be there, which one repeats, that the repetition is ordered, and that an empty value changes the question being asked rather than breaking it. Get those four and the whole authorization dictionary stops being a list to memorise.

  • What is the device asking when the argument list is `service=shell` and `cmd=`?
    For the shell itself. An empty `cmd` value makes it a session-based authorization: the device wants to bring up a command line and will apply whatever parameters come back — a `priv-lvl`, an `idletime`, a `timeout`. A populated `cmd` instead asks about one command that has just been typed.
  • Why does `cmd-arg` repeat instead of one argument holding the whole line?
    Because policy is written against the words. Splitting them and keeping them in order lets a server match a prefix of the command and stop, rather than string-matching a whole line. The ordering is part of the contract: the same words in a different order are a different command.
  • Does the device send `priv-lvl` to say what level the operator has?
    No. The session's current level travels in the REQUEST's fixed `priv_lvl` field. The hyphenated `priv-lvl` argument-value pair is normally what the server returns to assign a level to a shell. Two carriers of the same number, in opposite directions.

saying these in an interview costs you the question

  • Says the whole typed line travels in one cmd argument
  • Thinks cmd-arg order is irrelevant to the server
  • Treats service as optional when cmd is present
  • Claims an empty argument value is malformed
  • Says the device sends priv-lvl to state the operator's level
  • Believes the REQUEST also carries the operator's password
open as a page

In a TACACS+ authorization REPLY, what does PASS_ADD tell the network device to do that PASS_REPL does not?

level: seniorimportance: must knowfreq 48%

basics

~20 s

PASS_ADD keeps the device's own arguments and applies any returned ones in addition, so an arg_cnt of 0 approves the request exactly as sent. PASS_REPL obliges the device to discard what it sent and use the returned arguments instead.

open as a page

In TACACS+ per-command authorization, which side decides whether a typed command may run, and which side stops it?

level: juniorimportance: should knowfreq 38%

basics

~20 s

The device-administration server decides; the network device enforces. The device suspends the typed command, sends a TACACS+ authorization REQUEST describing it, and then runs or refuses it according to the single REPLY that comes back.

open as a page

What can the TACACS+ privilege-level scheme express about an operator, and what can it not express?

level: middleimportance: should knowfreq 44%

basics

~20 s

It expresses one number from an ordered range of sixteen, where each level is a superset of the one below. That makes seniority easy to state and a non-nested role impossible to state, which is why per-command matching on cmd and cmd-arg exists beside it.

open as a page

What does an '=' separator in a TACACS+ authorization argument oblige the network device to do that '*' does not?

level: seniorimportance: should knowfreq 33%

basics

~20 s

'=' marks the pair mandatory and '*' marks it optional. A device that receives a mandatory argument it cannot handle MUST evaluate the whole response as though the status were FAIL, so one unrecognised mandatory name turns an approval into a denial.

open as a page

Why must a TACACS+ server's authorization policy not branch on the authen_method value in the REQUEST?

level: seniorimportance: nice to knowfreq 24%

basics

~20 s

Because authen_method is the network device's own unverified claim about how the user was authenticated. RFC 8907 states the information is not always subject to verification and MUST NOT be used in policy evaluation; the server has no way to confirm it.

open as a page