libroot/posix/stdio: Remove unused portions.
[haiku.git] / src / bin / multiuser / su.cpp
blob9c2bdc5a25c0a4dd90ea6b21e9fa4e44e28cf22c
1 /*
2 * Copyright 2017, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 * Augustin Cavalier <waddlesplash>
8 */
11 #include <SupportDefs.h>
13 #include <errno.h>
14 #include <pwd.h>
15 #include <signal.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <syslog.h>
20 #include <termios.h>
21 #include <unistd.h>
23 #include "multiuser_utils.h"
26 extern const char* __progname;
27 const char* kProgramName = __progname;
29 const uint32 kRetries = 3;
32 static void
33 usage()
35 fprintf(stderr, "usage: %s [-pl] [-c command] [username]\n", kProgramName);
36 exit(1);
40 int
41 main(int argc, char *argv[])
43 bool loginShell = false;
44 const char* command = NULL;
46 char c;
47 while ((c = getopt(argc, argv, "c:l")) != -1) {
48 switch (c) {
49 case 'l':
50 loginShell = true;
51 break;
53 case 'c':
54 command = optarg;
55 break;
57 default:
58 usage();
59 break;
63 argc -= optind;
64 argv += optind;
66 const char* user = NULL;
67 if (argc > 0)
68 user = argv[0];
70 if (user == NULL)
71 user = "user";
72 // aka 'root' on Haiku
74 // login
76 openlog(kProgramName, 0, LOG_AUTH);
78 status_t status = B_ERROR;
79 struct passwd* passwd = NULL;
81 status = authenticate_user("password: ", user, &passwd, NULL,
82 kRetries, false);
84 if (status < B_OK || !passwd) {
85 if (passwd != NULL)
86 syslog(LOG_NOTICE, "su failed for \"%s\"", passwd->pw_name);
87 else
88 syslog(LOG_NOTICE, "su attempt for non-existent user \"%s\"", user);
89 exit(1);
92 // setup environment for the user
94 status = setup_environment(passwd, true, false);
95 if (status < B_OK) {
96 // refused login
97 fprintf(stderr, "%s: Refused login. Setting up environment failed: %s\n",
98 kProgramName, strerror(status));
99 syslog(LOG_NOTICE, "su refused for \"%s\"", passwd->pw_name);
100 exit(1);
103 syslog(LOG_INFO, "su as \"%s\"", passwd->pw_name);
105 // start shell
106 const char* args[] = {getenv("SHELL"), NULL, NULL, NULL, NULL};
107 int nextarg = 1;
108 if (loginShell) {
109 args[nextarg++] = "-login";
111 if (command != NULL) {
112 args[nextarg++] = "-c";
113 args[nextarg++] = command;
116 execv(args[0], (char **)args);
118 // try default shell
119 args[0] = "/bin/sh";
120 execv(args[0], (char **)args);
122 fprintf(stderr, "%s: starting the shell failed: %s", kProgramName,
123 strerror(errno));
125 return 1;