2 * Copyright 2007, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Axel Dörfler, axeld@pinc-software.de
10 #include <SupportDefs.h>
22 #include "multiuser_utils.h"
25 extern const char* __progname
;
26 const char* kProgramName
= __progname
;
28 const uint32 kRetries
= 3;
29 const uint32 kTimeout
= 60;
33 set_tty_echo(bool enabled
)
35 struct termios termios
;
37 if (ioctl(STDIN_FILENO
, TCGETA
, &termios
) != 0)
40 // do we have to change the current setting at all?
41 if (enabled
== ((termios
.c_lflag
& ECHO
) != 0))
45 termios
.c_lflag
|= ECHO
;
47 termios
.c_lflag
&= ~ECHO
;
49 if (ioctl(STDIN_FILENO
, TCSETA
, &termios
) != 0)
57 read_string(char* string
, size_t bufferSize
)
59 // TODO: setup timeout handler
61 // read everything until the next carriage return
63 while ((c
= fgetc(stdin
)) != EOF
&& c
!= '\r' && c
!= '\n') {
71 if (ferror(stdin
) != 0)
80 login(const char* user
, struct passwd
** _passwd
)
86 if (gethostname(host
, sizeof(host
)) != 0)
96 status_t status
= read_string(userBuffer
, sizeof(userBuffer
));
104 // if no user is given, we exit immediately
108 printf("password: ");
114 status_t status
= read_string(password
, sizeof(password
));
122 struct passwd
* passwd
= getpwnam(user
);
123 struct spwd
* spwd
= getspnam(user
);
125 bool ok
= verify_password(passwd
, spwd
, password
);
126 memset(password
, 0, sizeof(password
));
129 return B_PERMISSION_DENIED
;
137 setup_environment(struct passwd
* passwd
, bool preserveEnvironment
)
139 const char* term
= getenv("TERM");
140 if (!preserveEnvironment
) {
141 static char *empty
[1];
145 // always preserve $TERM
147 setenv("TERM", term
, false);
148 if (passwd
->pw_shell
)
149 setenv("SHELL", passwd
->pw_shell
, true);
151 setenv("HOME", passwd
->pw_dir
, true);
153 setenv("USER", passwd
->pw_name
, true);
155 pid_t pid
= getpid();
156 if (ioctl(STDIN_FILENO
, TIOCSPGRP
, &pid
) != 0)
159 const char* home
= getenv("HOME");
161 return B_ENTRY_NOT_FOUND
;
163 if (chdir(home
) != 0)
171 get_from(const char* host
)
176 static char buffer
[64];
177 snprintf(buffer
, sizeof(buffer
), " from %s", host
);
185 fprintf(stderr
, "usage: %s [-fp] [-h hostname] [username]\n", kProgramName
);
191 main(int argc
, char *argv
[])
193 bool noAuthentification
= false;
194 bool preserveEnvironment
= false;
195 const char* fromHost
= NULL
;
198 while ((c
= getopt(argc
, argv
, "fh:p")) != -1) {
201 noAuthentification
= true;
204 if (geteuid() != 0) {
205 fprintf(stderr
, "%s: %s\n", kProgramName
,
206 strerror(B_NOT_ALLOWED
));
213 preserveEnvironment
= true;
225 const char* user
= NULL
;
232 openlog(kProgramName
, 0, LOG_AUTH
);
234 uint32 retries
= kRetries
;
235 status_t status
= B_ERROR
;
236 struct passwd
* passwd
= NULL
;
238 while (retries
> 0) {
239 status
= login(user
, &passwd
);
243 fprintf(stderr
, "Login failed.\n");
247 // ask for the user name as well after the first failure
254 syslog(LOG_NOTICE
, "login%s failed for \"%s\"", get_from(fromHost
),
259 // setup environment for the user
261 status
= setup_environment(passwd
, preserveEnvironment
);
264 fprintf(stderr
, "%s: Refused login. Setting up environment failed: %s\n",
265 kProgramName
, strerror(status
));
266 syslog(LOG_NOTICE
, "login%s refused for \"%s\"", get_from(fromHost
),
271 syslog(LOG_INFO
, "login%s as \"%s\"", get_from(fromHost
), passwd
->pw_name
);
275 const char* args
[] = {getenv("SHELL"), "-login", NULL
};
276 execv(args
[0], (char **)args
);
280 execv(args
[0], (char **)args
);
282 fprintf(stderr
, "%s: starting the shell failed: %s", kProgramName
,