Compare commits

...

2 Commits

Author SHA1 Message Date
fe9d88e7f9 env flag
implemented -e flag:
it copies the elements of env that we want to keep, clears the environment and
sets it to only the saved and default elements.

also removed the code for copying the environment and allocating a new one
2021-04-04 19:34:10 +02:00
5412a3785e change env
us now changes the environment variables listed in TODO before executing the
command, also added but commented out a version where the env gets copied and
the execution happens trough the musl implementation of execvpe(3)
2021-04-04 12:42:03 +02:00

99
us.c
View File

@ -36,11 +36,14 @@ static int perm_set (struct passwd *, struct group *);
static int authenticate (const char *);
static struct passwd* user_to_passwd (const char *);
static struct group* group_to_grp (const char *);
//static int execvpe(const char *, char *const *, char *const *);
// FIXME: misc_conv is a separate library, should stick to plain PAM or make
// our own pam module
static struct pam_conv conv = {misc_conv, NULL};
extern char **environ;
int main (int argc, char *argv[])
{
// TODO: Add arguments
@ -48,9 +51,9 @@ int main (int argc, char *argv[])
char *t_usr = "root", *t_grp = NULL;
struct passwd *t_pw;
struct group *t_gr;
int opt;
int shellflag = 0;
while ((opt = getopt(argc, argv, "A:u:g:C:s")) != -1) {
int opt, err;
int shellflag = 0, envflag = 0;
while ((opt = getopt(argc, argv, "A:u:g:C:se")) != -1) {
switch (opt) {
case 'A':
printf("-A is not yet implemented\n");
@ -69,6 +72,9 @@ int main (int argc, char *argv[])
case 's':
shellflag = 1;
break;
case 'e':
envflag = 1;
break;
case '?':
usage();
exit(EINVAL);
@ -134,10 +140,53 @@ int main (int argc, char *argv[])
c_argv[c_argc] = NULL;
/* Authenticate */
// FIXME: move this up
if (authenticate(uname) != PAM_SUCCESS)
exit(EXIT_FAILURE);
// TODO: clean up env
struct env_elem {
char *name;
char *value;
};
struct env_elem env_keep[] = {
{"PATH", NULL},
{"TERM", NULL},
{"EDITOR", NULL},
{"VISUAL", NULL},
{"DISPLAY", NULL},
{"XAUTHORITY", NULL},
{NULL, NULL}
};
struct env_elem env_mod[] = {
{"USER", t_pw->pw_name},
{"LOGNAME", t_pw->pw_name},
{"SHELL", t_pw->pw_shell},
{"HOME", t_pw->pw_dir},
{NULL, NULL}
};
if (envflag) { /* clear env */
for (int i = 0; env_keep[i].name; i++)
env_keep[i].value = strdup(getenv(env_keep[i].name));
environ = NULL; // in place of clearenv
}
for (int i = 0; env_mod[i].name; i++) {
// TODO: check err value
err = setenv(env_mod[i].name, env_mod[i].value, 1);
}
if (envflag) {
for (int i = 0; env_keep[i].name; i++) {
// TODO: check err value
if (env_keep[i].value)
err = setenv(env_keep[i].name, env_keep[i].value, 1);
}
}
// do not override, we might be under more levels of 'us'
err = setenv("US_USER", my_pw->pw_name, 0);
errno = 0;
/* Set permissions */
@ -147,7 +196,6 @@ int main (int argc, char *argv[])
}
/* Execute the command */
int err;
err = execvp(c_argv[0], c_argv);
if (err == -1)
fprintf(stderr, "execl: %s\n", strerror(errno));
@ -171,7 +219,7 @@ static inline void usage (void)
// -c [file]: manually select config file
// something about environment
// something about non interactiveness
printf("usage: us [-s] [-u user] [-g group] command [args]\n");
printf("usage: us [-se] [-u user] [-g group] command [args]\n");
}
static int perm_set (struct passwd *pw, struct group *gr)
@ -305,3 +353,42 @@ static struct group* group_to_grp (const char *group)
}
return gr;
}
/*
static int execvpe(const char *file, char *const argv[], char *const envp[])
{
const char *p, *z, *path = getenv("PATH");
size_t l, k;
errno = ENOENT;
if (!*file) return -1;
if (strchr(file, '/'))
return execve(file, argv, envp);
if (!path) path = "/usr/local/bin:/bin:/usr/bin";
k = strnlen(file, NAME_MAX+1);
if (k > NAME_MAX) {
errno = ENAMETOOLONG;
return -1;
}
l = strnlen(path, PATH_MAX-1)+1;
for(p=path; ; p=z) {
char b[l+k+1];
z = strchr(p, ':');
if (!z) z = p+strlen(p);
if ((size_t)(z-p) >= l) {
if (!*z++) break;
continue;
}
memcpy(b, p, z-p);
b[z-p] = '/';
memcpy(b+(z-p)+(z>p), file, k+1);
execve(b, argv, envp);
if (errno != ENOENT) return -1;
if (!*z++) break;
}
return -1;
}
*/