Re: [hackers] [ubase][PATCH 1/4] su: simplify logic

2024-03-07 Thread neeshy
On Thu Mar 7, 2024 at 1:19 PM EST, Roberto E. Vargas Caballero wrote:
> I think it makes it simpler while keeping the correct behaviour that I broke.

Looks good to me!



Re: [hackers] [ubase][PATCH 1/4] su: simplify logic

2024-03-06 Thread neeshy
On Wed Mar 6, 2024 at 4:14 AM EST, Roberto E. Vargas Caballero wrote:
> Hi,
>
>
> On Mon, Feb 12, 2024 at 04:25:49PM -0500, neeshy wrote:
> > Inline dologin, and simplify common code
>
> I have applied the 4 patches with a minor modification to the 1st
> one.
>
> Kind regards,
> Roberto Vargas.

Hello,

It seems that the modifications you made break the use case where su is
called without a username. It would normally default to the root
user, but now it invokes usage() instead. My original patch worked as
intended. Could you rebase using the original patch instead? Thank you.



[hackers] [ubase][PATCH 3/4] su: check $SHELL for validity

2024-02-12 Thread neeshy
If $SHELL isn't defined in the environment, the call to execve will
fail when -p is specified. Fallback to the user's login shell if $SHELL
is invalid.
---
 su.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/su.c b/su.c
index 812aa43..4fc3c04 100644
--- a/su.c
+++ b/su.c
@@ -28,7 +28,7 @@ int
 main(int argc, char *argv[])
 {
char *usr = "root", *pass;
-   char *shell, *term;
+   char *shell, *envshell, *term;
struct passwd *pw;
char *newargv[3];
uid_t uid;
@@ -90,7 +90,9 @@ main(int argc, char *argv[])
newargv[2] = NULL;
} else {
if (pflag) {
-   shell = getenv("SHELL");
+   envshell = getenv("SHELL");
+   if (envshell && envshell[0] != '\0')
+   shell = envshell;
} else {
setenv("HOME", pw->pw_dir, 1);
setenv("SHELL", shell, 1);
-- 
2.43.1




[hackers] [ubase][PATCH 1/4] su: simplify logic

2024-02-12 Thread neeshy
Inline dologin, and simplify common code
---
 su.c | 69 
 1 file changed, 28 insertions(+), 41 deletions(-)

diff --git a/su.c b/su.c
index 329238f..bc7a94f 100644
--- a/su.c
+++ b/su.c
@@ -18,28 +18,6 @@ extern char **environ;
 static int lflag = 0;
 static int pflag = 0;
 
-static int
-dologin(struct passwd *pw)
-{
-   char *shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell;
-   char *term = getenv("TERM");
-   clearenv();
-   setenv("HOME", pw->pw_dir, 1);
-   setenv("SHELL", shell, 1);
-   setenv("USER", pw->pw_name, 1);
-   setenv("LOGNAME", pw->pw_name, 1);
-   setenv("TERM", term ? term : "linux", 1);
-   if (strcmp(pw->pw_name, "root") == 0)
-   setenv("PATH", ENV_SUPATH, 1);
-   else
-   setenv("PATH", ENV_PATH, 1);
-   if (chdir(pw->pw_dir) < 0)
-   eprintf("chdir %s:", pw->pw_dir);
-   execlp(shell, shell, "-l", NULL);
-   weprintf("execlp %s:", shell);
-   return (errno == ENOENT) ? 127 : 126;
-}
-
 static void
 usage(void)
 {
@@ -50,9 +28,9 @@ int
 main(int argc, char *argv[])
 {
char *usr = "root", *pass;
-   char *shell;
+   char *shell, *term;
struct passwd *pw;
-   char *newargv[2];
+   char *newargv[3];
uid_t uid;
 
ARGBEGIN {
@@ -66,11 +44,9 @@ main(int argc, char *argv[])
usage();
} ARGEND;
 
-   if (argc < 1)
-   ;
-   else if (argc == 1)
+   if (argc == 1)
usr = argv[0];
-   else
+   else if (argc > 1)
usage();
 
errno = 0;
@@ -98,13 +74,26 @@ main(int argc, char *argv[])
if (setuid(pw->pw_uid) < 0)
eprintf("setuid:");
 
+   shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell;
if (lflag) {
-   return dologin(pw);
+   newargv[0] = shell;
+   newargv[1] = "-l";
+   newargv[2] = NULL;
+   term = getenv("TERM");
+   clearenv();
+   setenv("HOME", pw->pw_dir, 1);
+   setenv("SHELL", shell, 1);
+   setenv("USER", pw->pw_name, 1);
+   setenv("LOGNAME", pw->pw_name, 1);
+   setenv("TERM", term ? term : "linux", 1);
+   if (chdir(pw->pw_dir) < 0)
+   eprintf("chdir %s:", pw->pw_dir);
} else {
-   shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell;
newargv[0] = shell;
newargv[1] = NULL;
-   if (!pflag) {
+   if (pflag) {
+   shell = getenv("SHELL");
+   } else {
setenv("HOME", pw->pw_dir, 1);
setenv("SHELL", shell, 1);
if (strcmp(pw->pw_name, "root") != 0) {
@@ -112,14 +101,12 @@ main(int argc, char *argv[])
setenv("LOGNAME", pw->pw_name, 1);
}
}
-   if (strcmp(pw->pw_name, "root") == 0)
-   setenv("PATH", ENV_SUPATH, 1);
-   else
-   setenv("PATH", ENV_PATH, 1);
-   execve(pflag ? getenv("SHELL") : shell,
-  newargv, environ);
-   weprintf("execve %s:", shell);
-   return (errno == ENOENT) ? 127 : 126;
}
-   return 0;
-}
\ No newline at end of file
+   if (strcmp(pw->pw_name, "root") == 0)
+   setenv("PATH", ENV_SUPATH, 1);
+   else
+   setenv("PATH", ENV_PATH, 1);
+   execve(shell, newargv, environ);
+   weprintf("execve %s:", shell);
+   return (errno == ENOENT) ? 127 : 126;
+}
-- 
2.43.1




[hackers] [ubase][PATCH 4/4] su: don't set $PATH

2024-02-12 Thread neeshy
Just /bin is too restrictive, and login shells set the path anyway via
the default profile. Also, carrying the path over for non-login shells
conforms to the behavior of util-linux's su.
---
 config.def.h | 1 -
 su.c | 5 -
 2 files changed, 6 deletions(-)

diff --git a/config.def.h b/config.def.h
index 577833e..257cfac 100644
--- a/config.def.h
+++ b/config.def.h
@@ -1,6 +1,5 @@
 /* See LICENSE file for copyright and license details. */
 
-#define ENV_SUPATH "/bin"
 #define ENV_PATH   "/bin"
 #define PW_CIPHER  "$6$"   /* SHA-512 */
 #undef UTMP_PATH
diff --git a/su.c b/su.c
index 4fc3c04..4fc72e8 100644
--- a/su.c
+++ b/su.c
@@ -9,7 +9,6 @@
 #include 
 #include 
 
-#include "config.h"
 #include "passwd.h"
 #include "util.h"
 
@@ -104,10 +103,6 @@ main(int argc, char *argv[])
newargv[0] = shell;
newargv[1] = NULL;
}
-   if (strcmp(pw->pw_name, "root") == 0)
-   setenv("PATH", ENV_SUPATH, 1);
-   else
-   setenv("PATH", ENV_PATH, 1);
execve(shell, newargv, environ);
weprintf("execve %s:", shell);
return (errno == ENOENT) ? 127 : 126;
-- 
2.43.1




[hackers] [ubase][PATCH 3/4] su: check $SHELL for validity

2024-02-12 Thread neeshy
If $SHELL isn't defined in the environment, the call to execve will
fail when -p is specified. Fallback to the user's login shell if $SHELL
is invalid.
---
 su.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/su.c b/su.c
index 812aa43..4fc3c04 100644
--- a/su.c
+++ b/su.c
@@ -28,7 +28,7 @@ int
 main(int argc, char *argv[])
 {
char *usr = "root", *pass;
-   char *shell, *term;
+   char *shell, *envshell, *term;
struct passwd *pw;
char *newargv[3];
uid_t uid;
@@ -90,7 +90,9 @@ main(int argc, char *argv[])
newargv[2] = NULL;
} else {
if (pflag) {
-   shell = getenv("SHELL");
+   envshell = getenv("SHELL");
+   if (envshell && envshell[0] != '\0')
+   shell = envshell;
} else {
setenv("HOME", pw->pw_dir, 1);
setenv("SHELL", shell, 1);
-- 
2.43.1




[hackers] [ubase][PATCH 1/4] su: simplify logic

2024-02-12 Thread neeshy
Inline dologin, and simplify common code
---
 su.c | 69 
 1 file changed, 28 insertions(+), 41 deletions(-)

diff --git a/su.c b/su.c
index 329238f..bc7a94f 100644
--- a/su.c
+++ b/su.c
@@ -18,28 +18,6 @@ extern char **environ;
 static int lflag = 0;
 static int pflag = 0;
 
-static int
-dologin(struct passwd *pw)
-{
-   char *shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell;
-   char *term = getenv("TERM");
-   clearenv();
-   setenv("HOME", pw->pw_dir, 1);
-   setenv("SHELL", shell, 1);
-   setenv("USER", pw->pw_name, 1);
-   setenv("LOGNAME", pw->pw_name, 1);
-   setenv("TERM", term ? term : "linux", 1);
-   if (strcmp(pw->pw_name, "root") == 0)
-   setenv("PATH", ENV_SUPATH, 1);
-   else
-   setenv("PATH", ENV_PATH, 1);
-   if (chdir(pw->pw_dir) < 0)
-   eprintf("chdir %s:", pw->pw_dir);
-   execlp(shell, shell, "-l", NULL);
-   weprintf("execlp %s:", shell);
-   return (errno == ENOENT) ? 127 : 126;
-}
-
 static void
 usage(void)
 {
@@ -50,9 +28,9 @@ int
 main(int argc, char *argv[])
 {
char *usr = "root", *pass;
-   char *shell;
+   char *shell, *term;
struct passwd *pw;
-   char *newargv[2];
+   char *newargv[3];
uid_t uid;
 
ARGBEGIN {
@@ -66,11 +44,9 @@ main(int argc, char *argv[])
usage();
} ARGEND;
 
-   if (argc < 1)
-   ;
-   else if (argc == 1)
+   if (argc == 1)
usr = argv[0];
-   else
+   else if (argc > 1)
usage();
 
errno = 0;
@@ -98,13 +74,26 @@ main(int argc, char *argv[])
if (setuid(pw->pw_uid) < 0)
eprintf("setuid:");
 
+   shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell;
if (lflag) {
-   return dologin(pw);
+   newargv[0] = shell;
+   newargv[1] = "-l";
+   newargv[2] = NULL;
+   term = getenv("TERM");
+   clearenv();
+   setenv("HOME", pw->pw_dir, 1);
+   setenv("SHELL", shell, 1);
+   setenv("USER", pw->pw_name, 1);
+   setenv("LOGNAME", pw->pw_name, 1);
+   setenv("TERM", term ? term : "linux", 1);
+   if (chdir(pw->pw_dir) < 0)
+   eprintf("chdir %s:", pw->pw_dir);
} else {
-   shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell;
newargv[0] = shell;
newargv[1] = NULL;
-   if (!pflag) {
+   if (pflag) {
+   shell = getenv("SHELL");
+   } else {
setenv("HOME", pw->pw_dir, 1);
setenv("SHELL", shell, 1);
if (strcmp(pw->pw_name, "root") != 0) {
@@ -112,14 +101,12 @@ main(int argc, char *argv[])
setenv("LOGNAME", pw->pw_name, 1);
}
}
-   if (strcmp(pw->pw_name, "root") == 0)
-   setenv("PATH", ENV_SUPATH, 1);
-   else
-   setenv("PATH", ENV_PATH, 1);
-   execve(pflag ? getenv("SHELL") : shell,
-  newargv, environ);
-   weprintf("execve %s:", shell);
-   return (errno == ENOENT) ? 127 : 126;
}
-   return 0;
-}
\ No newline at end of file
+   if (strcmp(pw->pw_name, "root") == 0)
+   setenv("PATH", ENV_SUPATH, 1);
+   else
+   setenv("PATH", ENV_PATH, 1);
+   execve(shell, newargv, environ);
+   weprintf("execve %s:", shell);
+   return (errno == ENOENT) ? 127 : 126;
+}
-- 
2.43.0




[hackers] [ubase][PATCH 2/4] su: fix setting argv0

2024-02-12 Thread neeshy
argv0 was being set to the user's login shell even when -p was
specified. Only populate newargv once the shell is properly determined.
---
 su.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/su.c b/su.c
index bc7a94f..812aa43 100644
--- a/su.c
+++ b/su.c
@@ -76,9 +76,6 @@ main(int argc, char *argv[])
 
shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell;
if (lflag) {
-   newargv[0] = shell;
-   newargv[1] = "-l";
-   newargv[2] = NULL;
term = getenv("TERM");
clearenv();
setenv("HOME", pw->pw_dir, 1);
@@ -88,9 +85,10 @@ main(int argc, char *argv[])
setenv("TERM", term ? term : "linux", 1);
if (chdir(pw->pw_dir) < 0)
eprintf("chdir %s:", pw->pw_dir);
-   } else {
newargv[0] = shell;
-   newargv[1] = NULL;
+   newargv[1] = "-l";
+   newargv[2] = NULL;
+   } else {
if (pflag) {
shell = getenv("SHELL");
} else {
@@ -101,6 +99,8 @@ main(int argc, char *argv[])
setenv("LOGNAME", pw->pw_name, 1);
}
}
+   newargv[0] = shell;
+   newargv[1] = NULL;
}
if (strcmp(pw->pw_name, "root") == 0)
setenv("PATH", ENV_SUPATH, 1);
-- 
2.43.0