diff options
author | Karel Zak | 2011-10-06 00:56:32 +0200 |
---|---|---|
committer | Karel Zak | 2011-10-26 23:17:17 +0200 |
commit | 92e386cac11b128ed2386df555478a79c6f5998e (patch) | |
tree | 2b2c0f3d0ef3c182d136b7105eefbc4a7d9f880f /login-utils/login.c | |
parent | login: use LOG_UNKFAIL_ENAB from login.defs, improve logging (diff) | |
download | kernel-qcow2-util-linux-92e386cac11b128ed2386df555478a79c6f5998e.tar.gz kernel-qcow2-util-linux-92e386cac11b128ed2386df555478a79c6f5998e.tar.xz kernel-qcow2-util-linux-92e386cac11b128ed2386df555478a79c6f5998e.zip |
login: add -H option for compatibility with Suse
Note that our login(1) uses hostname without domain, so:
"foo login: "
this is compatible with the default agetty(8) behavior.
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'login-utils/login.c')
-rw-r--r-- | login-utils/login.c | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/login-utils/login.c b/login-utils/login.c index e44aa5fc6..ed9a888ca 100644 --- a/login-utils/login.c +++ b/login-utils/login.c @@ -106,13 +106,16 @@ struct login_context { char vcsan[VCS_PATH_MAX]; #endif - char *hostname; - char hostaddress[16]; + char thishost[MAXHOSTNAMELEN + 1]; /* this machine */ + char *thisdomain; /* this machine domain */ + char *hostname; /* remote machine */ + char hostaddress[16]; /* remote address */ pid_t pid; int quiet; /* 1 is hush file exists */ unsigned int remote:1, /* login -h */ + nohost:1, /* login -H */ noauth:1, /* login -f */ keep_env:1; /* login -p */ }; @@ -181,6 +184,25 @@ static void sleepexit(int eval) exit(eval); } +static const char *get_thishost(struct login_context *cxt, const char **domain) +{ + if (!*cxt->thishost) { + if (gethostname(cxt->thishost, sizeof(cxt->thishost))) { + if (domain) + *domain = NULL; + return NULL; + } + cxt->thishost[sizeof(cxt->thishost) -1] = '\0'; + cxt->thisdomain = strchr(cxt->thishost, '.'); + if (cxt->thisdomain) + *cxt->thisdomain++ = '\0'; + } + + if (domain) + *domain = cxt->thisdomain; + return cxt->thishost; +} + /* * Output the /etc/motd file * @@ -663,6 +685,26 @@ static int loginpam_err(pam_handle_t *pamh, int retcode) } +/* + * Composes "<host> login: " string; or returns "login: " is -H is given + */ +static const char *loginpam_get_prompt(struct login_context *cxt) +{ + const char *host; + char *prompt, *dflt_prompt = _("login: "); + size_t sz; + + if (cxt->nohost || !(host = get_thishost(cxt, NULL))) + return dflt_prompt; + + sz = strlen(host) + 1 + strlen(dflt_prompt) + 1; + + prompt = xmalloc(sz); + snprintf(prompt, sz, "%s %s", host, dflt_prompt); + + return prompt; +} + static pam_handle_t *init_loginpam(struct login_context *cxt) { pam_handle_t *pamh = NULL; @@ -697,7 +739,7 @@ static pam_handle_t *init_loginpam(struct login_context *cxt) * the "login: " prompt gets localized. Unfortunately, PAM doesn't have * an interface to specify the "Password: " string (yet). */ - rc = pam_set_item(pamh, PAM_USER_PROMPT, _("login: ")); + rc = pam_set_item(pamh, PAM_USER_PROMPT, loginpam_get_prompt(cxt)); if (is_pam_failure(rc)) loginpam_err(pamh, rc); @@ -1093,16 +1135,16 @@ static void init_environ(struct login_context *cxt) */ static void init_remote_info(struct login_context *cxt, char *remotehost) { - char host[MAXHOSTNAMELEN + 1]; - char *domain = NULL, *p; + const char *domain; + char *p; struct addrinfo hints, *info = NULL; cxt->remote = 1; - if (gethostname(host, sizeof(host)) == 0) - domain = strchr(host, '.'); + get_thishost(cxt, &domain); - if (domain && (p = strchr(remotehost, '.')) && strcasecmp(p, domain) == 0) + if (domain && (p = strchr(remotehost, '.')) && + strcasecmp(p + 1, domain) == 0) *p = '\0'; cxt->hostname = xstrdup(remotehost); @@ -1167,12 +1209,16 @@ int main(int argc, char **argv) * -h is used by other servers to pass the name of the remote * host to login so that it may be placed in utmp and wtmp */ - while ((c = getopt(argc, argv, "fh:p")) != -1) + while ((c = getopt(argc, argv, "fHh:p")) != -1) switch (c) { case 'f': cxt.noauth = 1; break; + case 'H': + cxt.nohost = 1; + break; + case 'h': if (getuid()) { fprintf(stderr, @@ -1188,7 +1234,7 @@ int main(int argc, char **argv) case '?': default: - fprintf(stderr, _("usage: login [-fp] [username]\n")); + fprintf(stderr, _("usage: login [ -p ] [ -h host ] [ -H ] [ -f username | username ]\n")); exit(EXIT_FAILURE); } argc -= optind; |