upstream commit
add AuthorizedPrincipalsCommand that allows getting authorized_principals from a subprocess rather than a file, which is quite useful in deployments with large userbases feedback and ok markus@ Upstream-ID: aa1bdac7b16fc6d2fa3524ef08f04c7258d247f6
This commit is contained in:
parent
24232a3e5a
commit
bcc50d8161
152
auth2-pubkey.c
152
auth2-pubkey.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: auth2-pubkey.c,v 1.50 2015/05/21 06:38:35 djm Exp $ */
|
/* $OpenBSD: auth2-pubkey.c,v 1.51 2015/05/21 06:43:30 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -554,19 +554,13 @@ match_principals_option(const char *principal_list, struct sshkey_cert *cert)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert)
|
process_principals(FILE *f, char *file, struct passwd *pw,
|
||||||
|
struct sshkey_cert *cert)
|
||||||
{
|
{
|
||||||
FILE *f;
|
|
||||||
char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts;
|
char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts;
|
||||||
u_long linenum = 0;
|
u_long linenum = 0;
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
temporarily_use_uid(pw);
|
|
||||||
debug("trying authorized principals file %s", file);
|
|
||||||
if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) {
|
|
||||||
restore_uid();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
|
while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
|
||||||
/* Skip leading whitespace. */
|
/* Skip leading whitespace. */
|
||||||
for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
|
for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
|
||||||
|
@ -594,23 +588,127 @@ match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert)
|
||||||
}
|
}
|
||||||
for (i = 0; i < cert->nprincipals; i++) {
|
for (i = 0; i < cert->nprincipals; i++) {
|
||||||
if (strcmp(cp, cert->principals[i]) == 0) {
|
if (strcmp(cp, cert->principals[i]) == 0) {
|
||||||
debug3("matched principal \"%.100s\" "
|
debug3("%s:%lu: matched principal \"%.100s\"",
|
||||||
"from file \"%s\" on line %lu",
|
file == NULL ? "(command)" : file,
|
||||||
cert->principals[i], file, linenum);
|
linenum, cert->principals[i]);
|
||||||
if (auth_parse_options(pw, line_opts,
|
if (auth_parse_options(pw, line_opts,
|
||||||
file, linenum) != 1)
|
file, linenum) != 1)
|
||||||
continue;
|
continue;
|
||||||
fclose(f);
|
|
||||||
restore_uid();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
restore_uid();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
int success;
|
||||||
|
|
||||||
|
temporarily_use_uid(pw);
|
||||||
|
debug("trying authorized principals file %s", file);
|
||||||
|
if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) {
|
||||||
|
restore_uid();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
success = process_principals(f, file, pw, cert);
|
||||||
|
fclose(f);
|
||||||
|
restore_uid();
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks whether principal is allowed in output of command.
|
||||||
|
* returns 1 if the principal is allowed or 0 otherwise.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
match_principals_command(struct passwd *user_pw, struct sshkey *key)
|
||||||
|
{
|
||||||
|
FILE *f = NULL;
|
||||||
|
int ok, found_principal = 0;
|
||||||
|
struct passwd *pw;
|
||||||
|
int i, ac = 0, uid_swapped = 0;
|
||||||
|
pid_t pid;
|
||||||
|
char *tmp, *username = NULL, *command = NULL, **av = NULL;
|
||||||
|
void (*osigchld)(int);
|
||||||
|
|
||||||
|
if (options.authorized_principals_command == NULL)
|
||||||
|
return 0;
|
||||||
|
if (options.authorized_principals_command_user == NULL) {
|
||||||
|
error("No user for AuthorizedPrincipalsCommand specified, "
|
||||||
|
"skipping");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NB. all returns later this function should go via "out" to
|
||||||
|
* ensure the original SIGCHLD handler is restored properly.
|
||||||
|
*/
|
||||||
|
osigchld = signal(SIGCHLD, SIG_DFL);
|
||||||
|
|
||||||
|
/* Prepare and verify the user for the command */
|
||||||
|
username = percent_expand(options.authorized_principals_command_user,
|
||||||
|
"u", user_pw->pw_name, (char *)NULL);
|
||||||
|
pw = getpwnam(username);
|
||||||
|
if (pw == NULL) {
|
||||||
|
error("AuthorizedPrincipalsCommandUser \"%s\" not found: %s",
|
||||||
|
username, strerror(errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn the command into an argument vector */
|
||||||
|
if (split_argv(options.authorized_principals_command, &ac, &av) != 0) {
|
||||||
|
error("AuthorizedPrincipalsCommand \"%s\" contains "
|
||||||
|
"invalid quotes", command);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (ac == 0) {
|
||||||
|
error("AuthorizedPrincipalsCommand \"%s\" yielded no arguments",
|
||||||
|
command);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
for (i = 1; i < ac; i++) {
|
||||||
|
tmp = percent_expand(av[i],
|
||||||
|
"u", user_pw->pw_name,
|
||||||
|
"h", user_pw->pw_dir,
|
||||||
|
(char *)NULL);
|
||||||
|
if (tmp == NULL)
|
||||||
|
fatal("%s: percent_expand failed", __func__);
|
||||||
|
free(av[i]);
|
||||||
|
av[i] = tmp;
|
||||||
|
}
|
||||||
|
/* Prepare a printable command for logs, etc. */
|
||||||
|
command = assemble_argv(ac, av);
|
||||||
|
|
||||||
|
if ((pid = subprocess("AuthorizedPrincipalsCommand", pw, command,
|
||||||
|
ac, av, &f)) == 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
uid_swapped = 1;
|
||||||
|
temporarily_use_uid(pw);
|
||||||
|
|
||||||
|
ok = process_principals(f, NULL, pw, key->cert);
|
||||||
|
|
||||||
|
if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Read completed successfully */
|
||||||
|
found_principal = ok;
|
||||||
|
out:
|
||||||
|
if (f != NULL)
|
||||||
|
fclose(f);
|
||||||
|
signal(SIGCHLD, osigchld);
|
||||||
|
for (i = 0; i < ac; i++)
|
||||||
|
free(av[i]);
|
||||||
|
free(av);
|
||||||
|
if (uid_swapped)
|
||||||
|
restore_uid();
|
||||||
|
free(command);
|
||||||
|
free(username);
|
||||||
|
return found_principal;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Checks whether key is allowed in authorized_keys-format file,
|
* Checks whether key is allowed in authorized_keys-format file,
|
||||||
* returns 1 if the key is allowed or 0 otherwise.
|
* returns 1 if the key is allowed or 0 otherwise.
|
||||||
|
@ -733,7 +831,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
|
||||||
{
|
{
|
||||||
char *ca_fp, *principals_file = NULL;
|
char *ca_fp, *principals_file = NULL;
|
||||||
const char *reason;
|
const char *reason;
|
||||||
int ret = 0;
|
int ret = 0, found_principal = 0;
|
||||||
|
|
||||||
if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
|
if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -755,14 +853,20 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
|
||||||
* against the username.
|
* against the username.
|
||||||
*/
|
*/
|
||||||
if ((principals_file = authorized_principals_file(pw)) != NULL) {
|
if ((principals_file = authorized_principals_file(pw)) != NULL) {
|
||||||
if (!match_principals_file(principals_file, pw, key->cert)) {
|
if (match_principals_file(principals_file, pw, key->cert))
|
||||||
reason = "Certificate does not contain an "
|
found_principal = 1;
|
||||||
"authorized principal";
|
}
|
||||||
|
/* Try querying command if specified */
|
||||||
|
if (!found_principal && match_principals_command(pw, key))
|
||||||
|
found_principal = 1;
|
||||||
|
/* If principals file or command specify, then require a match here */
|
||||||
|
if (!found_principal && (principals_file != NULL ||
|
||||||
|
options.authorized_principals_command != NULL)) {
|
||||||
|
reason = "Certificate does not contain an authorized principal";
|
||||||
fail_reason:
|
fail_reason:
|
||||||
error("%s", reason);
|
error("%s", reason);
|
||||||
auth_debug_add("%s", reason);
|
auth_debug_add("%s", reason);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (key_cert_check_authority(key, 0, 1,
|
if (key_cert_check_authority(key, 0, 1,
|
||||||
principals_file == NULL ? pw->pw_name : NULL, &reason) != 0)
|
principals_file == NULL ? pw->pw_name : NULL, &reason) != 0)
|
||||||
|
|
37
servconf.c
37
servconf.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: servconf.c,v 1.269 2015/05/04 06:10:48 djm Exp $ */
|
/* $OpenBSD: servconf.c,v 1.270 2015/05/21 06:43:30 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
|
@ -160,6 +160,8 @@ initialize_server_options(ServerOptions *options)
|
||||||
options->revoked_keys_file = NULL;
|
options->revoked_keys_file = NULL;
|
||||||
options->trusted_user_ca_keys = NULL;
|
options->trusted_user_ca_keys = NULL;
|
||||||
options->authorized_principals_file = NULL;
|
options->authorized_principals_file = NULL;
|
||||||
|
options->authorized_principals_command = NULL;
|
||||||
|
options->authorized_principals_command_user = NULL;
|
||||||
options->ip_qos_interactive = -1;
|
options->ip_qos_interactive = -1;
|
||||||
options->ip_qos_bulk = -1;
|
options->ip_qos_bulk = -1;
|
||||||
options->version_addendum = NULL;
|
options->version_addendum = NULL;
|
||||||
|
@ -400,6 +402,7 @@ typedef enum {
|
||||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||||
sHostCertificate,
|
sHostCertificate,
|
||||||
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
|
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
|
||||||
|
sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
|
||||||
sKexAlgorithms, sIPQoS, sVersionAddendum,
|
sKexAlgorithms, sIPQoS, sVersionAddendum,
|
||||||
sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
|
sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
|
||||||
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
|
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
|
||||||
|
@ -532,6 +535,8 @@ static struct {
|
||||||
{ "ipqos", sIPQoS, SSHCFG_ALL },
|
{ "ipqos", sIPQoS, SSHCFG_ALL },
|
||||||
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
|
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
|
||||||
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
|
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
|
||||||
|
{ "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
|
||||||
|
{ "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
|
||||||
{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
|
{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
|
||||||
{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
|
{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
|
||||||
{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
|
{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
|
||||||
|
@ -1734,6 +1739,34 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||||
*charptr = xstrdup(arg);
|
*charptr = xstrdup(arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case sAuthorizedPrincipalsCommand:
|
||||||
|
if (cp == NULL)
|
||||||
|
fatal("%.200s line %d: Missing argument.", filename,
|
||||||
|
linenum);
|
||||||
|
len = strspn(cp, WHITESPACE);
|
||||||
|
if (*activep &&
|
||||||
|
options->authorized_principals_command == NULL) {
|
||||||
|
if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
|
||||||
|
fatal("%.200s line %d: "
|
||||||
|
"AuthorizedPrincipalsCommand must be "
|
||||||
|
"an absolute path", filename, linenum);
|
||||||
|
options->authorized_principals_command =
|
||||||
|
xstrdup(cp + len);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case sAuthorizedPrincipalsCommandUser:
|
||||||
|
charptr = &options->authorized_principals_command_user;
|
||||||
|
|
||||||
|
arg = strdelim(&cp);
|
||||||
|
if (!arg || *arg == '\0')
|
||||||
|
fatal("%s line %d: missing "
|
||||||
|
"AuthorizedPrincipalsCommandUser argument.",
|
||||||
|
filename, linenum);
|
||||||
|
if (*activep && *charptr == NULL)
|
||||||
|
*charptr = xstrdup(arg);
|
||||||
|
break;
|
||||||
|
|
||||||
case sAuthenticationMethods:
|
case sAuthenticationMethods:
|
||||||
if (options->num_auth_methods == 0) {
|
if (options->num_auth_methods == 0) {
|
||||||
while ((arg = strdelim(&cp)) && *arg != '\0') {
|
while ((arg = strdelim(&cp)) && *arg != '\0') {
|
||||||
|
@ -2229,6 +2262,8 @@ dump_config(ServerOptions *o)
|
||||||
? "none" : o->version_addendum);
|
? "none" : o->version_addendum);
|
||||||
dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
|
dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
|
||||||
dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
|
dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
|
||||||
|
dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
|
||||||
|
dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
|
||||||
dump_cfg_string(sHostKeyAgent, o->host_key_agent);
|
dump_cfg_string(sHostKeyAgent, o->host_key_agent);
|
||||||
dump_cfg_string(sKexAlgorithms,
|
dump_cfg_string(sKexAlgorithms,
|
||||||
o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX);
|
o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX);
|
||||||
|
|
10
servconf.h
10
servconf.h
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: servconf.h,v 1.117 2015/04/29 03:48:56 dtucker Exp $ */
|
/* $OpenBSD: servconf.h,v 1.118 2015/05/21 06:43:31 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
|
@ -178,9 +178,11 @@ typedef struct {
|
||||||
char *chroot_directory;
|
char *chroot_directory;
|
||||||
char *revoked_keys_file;
|
char *revoked_keys_file;
|
||||||
char *trusted_user_ca_keys;
|
char *trusted_user_ca_keys;
|
||||||
char *authorized_principals_file;
|
|
||||||
char *authorized_keys_command;
|
char *authorized_keys_command;
|
||||||
char *authorized_keys_command_user;
|
char *authorized_keys_command_user;
|
||||||
|
char *authorized_principals_file;
|
||||||
|
char *authorized_principals_command;
|
||||||
|
char *authorized_principals_command_user;
|
||||||
|
|
||||||
int64_t rekey_limit;
|
int64_t rekey_limit;
|
||||||
int rekey_interval;
|
int rekey_interval;
|
||||||
|
@ -216,9 +218,11 @@ struct connection_info {
|
||||||
M_CP_STROPT(banner); \
|
M_CP_STROPT(banner); \
|
||||||
M_CP_STROPT(trusted_user_ca_keys); \
|
M_CP_STROPT(trusted_user_ca_keys); \
|
||||||
M_CP_STROPT(revoked_keys_file); \
|
M_CP_STROPT(revoked_keys_file); \
|
||||||
M_CP_STROPT(authorized_principals_file); \
|
|
||||||
M_CP_STROPT(authorized_keys_command); \
|
M_CP_STROPT(authorized_keys_command); \
|
||||||
M_CP_STROPT(authorized_keys_command_user); \
|
M_CP_STROPT(authorized_keys_command_user); \
|
||||||
|
M_CP_STROPT(authorized_principals_file); \
|
||||||
|
M_CP_STROPT(authorized_principals_command); \
|
||||||
|
M_CP_STROPT(authorized_principals_command_user); \
|
||||||
M_CP_STROPT(hostbased_key_types); \
|
M_CP_STROPT(hostbased_key_types); \
|
||||||
M_CP_STROPT(pubkey_key_types); \
|
M_CP_STROPT(pubkey_key_types); \
|
||||||
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
|
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
|
||||||
|
|
7
sshd.c
7
sshd.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: sshd.c,v 1.448 2015/04/27 00:21:21 djm Exp $ */
|
/* $OpenBSD: sshd.c,v 1.449 2015/05/21 06:43:31 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
|
@ -1698,6 +1698,11 @@ main(int ac, char **av)
|
||||||
strcasecmp(options.authorized_keys_command, "none") != 0))
|
strcasecmp(options.authorized_keys_command, "none") != 0))
|
||||||
fatal("AuthorizedKeysCommand set without "
|
fatal("AuthorizedKeysCommand set without "
|
||||||
"AuthorizedKeysCommandUser");
|
"AuthorizedKeysCommandUser");
|
||||||
|
if (options.authorized_principals_command_user == NULL &&
|
||||||
|
(options.authorized_principals_command != NULL &&
|
||||||
|
strcasecmp(options.authorized_principals_command, "none") != 0))
|
||||||
|
fatal("AuthorizedPrincipalsCommand set without "
|
||||||
|
"AuthorizedPrincipalsCommandUser");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether there is any path through configured auth methods.
|
* Check whether there is any path through configured auth methods.
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" $OpenBSD: sshd_config.5,v 1.201 2015/05/21 06:38:35 djm Exp $
|
.\" $OpenBSD: sshd_config.5,v 1.202 2015/05/21 06:43:31 djm Exp $
|
||||||
.Dd $Mdocdate: May 21 2015 $
|
.Dd $Mdocdate: May 21 2015 $
|
||||||
.Dt SSHD_CONFIG 5
|
.Dt SSHD_CONFIG 5
|
||||||
.Os
|
.Os
|
||||||
|
@ -287,6 +287,42 @@ directory.
|
||||||
Multiple files may be listed, separated by whitespace.
|
Multiple files may be listed, separated by whitespace.
|
||||||
The default is
|
The default is
|
||||||
.Dq .ssh/authorized_keys .ssh/authorized_keys2 .
|
.Dq .ssh/authorized_keys .ssh/authorized_keys2 .
|
||||||
|
.It Cm AuthorizedPrincipalsCommand
|
||||||
|
Specifies a program to be used to generate the list of allowed
|
||||||
|
certificate principals as per
|
||||||
|
.Cm AuthorizedPrincipalsFile .
|
||||||
|
The program must be owned by root, not writable by group or others and
|
||||||
|
specified by an absolute path.
|
||||||
|
.Pp
|
||||||
|
Arguments to
|
||||||
|
.Cm AuthorizedPrincipalsCommand
|
||||||
|
may be provided using the following tokens, which will be expanded
|
||||||
|
at runtime: %% is replaced by a literal '%', %u is replaced by the
|
||||||
|
username being authenticated and %h is replaced by the home directory
|
||||||
|
of the user being authenticated.
|
||||||
|
.Pp
|
||||||
|
The program should produce on standard output zero or
|
||||||
|
more lines of
|
||||||
|
.Cm AuthorizedPrincipalsFile
|
||||||
|
output.
|
||||||
|
If either
|
||||||
|
.Cm AuthorizedPrincipalsCommand
|
||||||
|
or
|
||||||
|
.Cm AuthorizedPrincipalsFile
|
||||||
|
is specified, then certificates offered by the client for authentication
|
||||||
|
must contain a principal that is listed.
|
||||||
|
By default, no AuthorizedPrincipalsCommand is run.
|
||||||
|
.It Cm AuthorizedPrincipalsCommandUser
|
||||||
|
Specifies the user under whose account the AuthorizedPrincipalsCommand is run.
|
||||||
|
It is recommended to use a dedicated user that has no other role on the host
|
||||||
|
than running authorized principals commands.
|
||||||
|
If
|
||||||
|
.Cm AuthorizedPrincipalsCommand
|
||||||
|
is specified but
|
||||||
|
.Cm AuthorizedPrincipalsCommandUser
|
||||||
|
is not, then
|
||||||
|
.Xr sshd 8
|
||||||
|
will refuse to start.
|
||||||
.It Cm AuthorizedPrincipalsFile
|
.It Cm AuthorizedPrincipalsFile
|
||||||
Specifies a file that lists principal names that are accepted for
|
Specifies a file that lists principal names that are accepted for
|
||||||
certificate authentication.
|
certificate authentication.
|
||||||
|
|
Loading…
Reference in New Issue