1 /* $OpenBSD: login.c,v 1.18 2018/06/13 15:02:09 reyk Exp $ */
4 * Copyright (c) 1995 Berkeley Software Design, Inc. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Berkeley Software Design,
18 * 4. The name of Berkeley Software Design, Inc. may not be used to endorse
19 * or promote products derived from this software without specific prior
22 * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * BSDI $From: login_passwd.c,v 1.11 1997/08/08 18:58:24 prb Exp $
42 main(int argc
, char **argv
)
44 int opt
, mode
= 0, ret
, lastchance
= 0;
45 char *username
, *password
= NULL
;
48 int arg_login
= 0, arg_notickets
= 0;
49 char invokinguser
[LOGIN_NAME_MAX
];
50 char *wheel
= NULL
, *class = NULL
;
52 struct passwd
*pwd
, *pwd_save
;
55 invokinguser
[0] = '\0';
57 setpriority(PRIO_PROCESS
, 0, 0);
59 openlog(NULL
, LOG_ODELAY
, LOG_AUTH
);
61 while ((opt
= getopt(argc
, argv
, "ds:v:")) != -1) {
66 case 's': /* service */
67 if (strcmp(optarg
, "login") == 0)
69 else if (strcmp(optarg
, "challenge") == 0)
70 mode
= MODE_CHALLENGE
;
71 else if (strcmp(optarg
, "response") == 0)
74 syslog(LOG_ERR
, "%s: invalid service", optarg
);
79 if (strncmp(optarg
, "wheel=", 6) == 0)
81 else if (strncmp(optarg
, "lastchance=", 11) == 0)
82 lastchance
= (strcmp(optarg
+ 11, "yes") == 0);
83 else if (strcmp(optarg
, "login=yes") == 0)
85 else if (strcmp(optarg
, "notickets=yes") == 0)
87 else if (strncmp(optarg
, "invokinguser=", 13) == 0)
88 snprintf(invokinguser
, sizeof(invokinguser
),
90 /* Silently ignore unsupported variables */
93 syslog(LOG_ERR
, "usage error1");
98 switch (argc
- optind
) {
100 class = argv
[optind
+ 1];
103 username
= argv
[optind
];
106 syslog(LOG_ERR
, "usage error2");
111 /* get the password hash before pledge(2) or it will return '*' */
112 pwd
= getpwnam_shadow(username
);
113 if (pwd
== NULL
|| (pwd_save
= pw_dup(pwd
)) == NULL
)
117 if ((arg_login
) && (!arg_notickets
)) {
118 if (pledge("stdio rpath tty id getpw dns inet flock cpath wpath chown", NULL
) == -1) {
119 syslog(LOG_ERR
, "pledge: %m");
123 if (pledge("stdio rpath tty id getpw dns inet flock", NULL
) == -1) {
124 syslog(LOG_ERR
, "pledge: %m");
129 if (back
== NULL
&& (back
= fdopen(3, "r+")) == NULL
) {
130 syslog(LOG_ERR
, "reopening back channel: %m");
135 * Read password, either as from the terminal or if the
136 * response mode is active from the caller program.
138 * XXX This is completely ungrokkable, and should be rewritten.
141 case MODE_RESPONSE
: {
145 while (++count
< sizeof(response
) &&
146 read(3, &response
[count
], 1) == 1) {
147 if (response
[count
] == '\0' && ++mode
== 2)
149 if (response
[count
] == '\0' && mode
== 1) {
150 password
= response
+ count
+ 1;
154 syslog(LOG_ERR
, "protocol error on back channel");
161 password
= readpassphrase("Password:", pbuf
, sizeof(pbuf
), RPP_ECHO_OFF
);
164 fprintf(back
, BI_SILENT
"\n");
168 syslog(LOG_ERR
, "%d: unknown mode", mode
);
174 ret
= krb5_login(username
, invokinguser
, password
, arg_login
,
175 !arg_notickets
, class);
178 ret
= pwd_login(username
, password
, wheel
, lastchance
, class, pwd_save
);
182 if (password
!= NULL
)
183 explicit_bzero(password
, strlen(password
));
185 fprintf(back
, BI_REJECT
"\n");