static const security_context_t selinux_get_user_context(const char *name) { security_context_t user_context=NULL; char *role=NULL; int ret = -1; char *seuser=NULL; char *level=NULL; if (the_authctxt) role=the_authctxt->role; if (getseuserbyname(name, &seuser, &level)==0) { if (role != NULL && role[0]) ret=get_default_context_with_rolelevel(seuser, role, level,NULL, &user_context); else ret=get_default_context_with_level(seuser, level, NULL,&user_context); } if ( ret < 0 ) { if (security_getenforce() > 0) fatal("Failed to get default security context for %s.", name); else error("Failed to get default security context for %s." "Continuing in permissive mode", name); } return user_context; }
/* Return the default security context for the given username */ static security_context_t ssh_selinux_getctxbyname(char *pwname) { security_context_t sc = NULL; char *sename = NULL, *lvl = NULL; int r; #ifdef HAVE_GETSEUSERBYNAME if (getseuserbyname(pwname, &sename, &lvl) != 0) return NULL; #else sename = pwname; lvl = NULL; #endif #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL r = get_default_context_with_level(sename, lvl, NULL, &sc); #else r = get_default_context(sename, NULL, &sc); #endif if (r != 0) { switch (security_getenforce()) { case -1: fatal("%s: ssh_selinux_getctxbyname: " "security_getenforce() failed", __func__); case 0: error("%s: Failed to get default SELinux security " "context for %s", __func__, pwname); sc = NULL; break; default: fatal("%s: Failed to get default SELinux security " "context for %s (in enforcing mode)", __func__, pwname); } } #ifdef HAVE_GETSEUSERBYNAME if (sename != NULL) xfree(sename); if (lvl != NULL) xfree(lvl); #endif return sc; }
// sushell.cmt static void sushell(struct passwd *pwd) { char shell[128]; char home[128]; char *p; char *sushell; /* * Set directory and shell. */ (void)chdir(pwd->pw_dir); if ((p = getenv("SUSHELL")) != NULL) sushell = p; else if ((p = getenv("sushell")) != NULL) sushell = p; else { if (pwd->pw_shell[0]) sushell = pwd->pw_shell; else sushell = BINSH; } if ((p = strrchr(sushell, '/')) == NULL) p = sushell; else p++; snprintf(shell, sizeof(shell), profile ? "-%s" : "%s", p); /* * Set some important environment variables. */ getcwd(home, sizeof(home)); setenv("HOME", home, 1); setenv("LOGNAME", "root", 1); setenv("USER", "root", 1); if (!profile) setenv("SHLVL","0",1); /* * Try to execute a shell. */ setenv("SHELL", sushell, 1); signal(SIGINT, saved_sigint); signal(SIGTSTP, saved_sigtstp); signal(SIGQUIT, saved_sigquit); #ifdef WITH_SELINUX if (is_selinux_enabled() > 0) { security_context_t scon=NULL; char *seuser=NULL; char *level=NULL; if (getseuserbyname("root", &seuser, &level) == 0) if (get_default_context_with_level(seuser, level, 0, &scon) == 0) { if (setexeccon(scon) != 0) fprintf(stderr, "setexeccon faile\n"); freecon(scon); } free(seuser); free(level); } #endif execl(sushell, shell, NULL); perror(sushell); setenv("SHELL", BINSH, 1); execl(BINSH, profile ? "-sh" : "sh", NULL); perror(BINSH); /* Fall back to staticly linked shell if both the users shell and /bin/sh failed to execute. */ setenv("SHELL", STATICSH, 1); execl(STATICSH, STATICSH, NULL); perror(STATICSH); }
/* * Password was OK, execute a shell. */ static void sushell(struct passwd *pwd) { char shell[PATH_MAX]; char home[PATH_MAX]; char *p; char *su_shell; /* * Set directory and shell. */ if (chdir(pwd->pw_dir) != 0) { warn(_("%s: change directory failed"), pwd->pw_dir); printf(_("Logging in with home = \"/\".\n")); if (chdir("/") != 0) warn(_("change directory to system root failed")); } if ((p = getenv("SUSHELL")) != NULL) su_shell = p; else if ((p = getenv("sushell")) != NULL) su_shell = p; else { if (pwd->pw_shell[0]) su_shell = pwd->pw_shell; else su_shell = "/bin/sh"; } if ((p = strrchr(su_shell, '/')) == NULL) p = su_shell; else p++; snprintf(shell, sizeof(shell), profile ? "-%s" : "%s", p); /* * Set some important environment variables. */ if (getcwd(home, sizeof(home)) != NULL) setenv("HOME", home, 1); setenv("LOGNAME", "root", 1); setenv("USER", "root", 1); if (!profile) setenv("SHLVL","0",1); /* * Try to execute a shell. */ setenv("SHELL", su_shell, 1); unmask_signal(SIGINT, &saved_sigint); unmask_signal(SIGTSTP, &saved_sigtstp); unmask_signal(SIGQUIT, &saved_sigquit); #ifdef HAVE_LIBSELINUX if (is_selinux_enabled() > 0) { security_context_t scon=NULL; char *seuser=NULL; char *level=NULL; if (getseuserbyname("root", &seuser, &level) == 0) { if (get_default_context_with_level(seuser, level, 0, &scon) == 0) { if (setexeccon(scon) != 0) warnx(_("setexeccon failed")); freecon(scon); } } free(seuser); free(level); } #endif execl(su_shell, shell, NULL); warn(_("%s: exec failed"), su_shell); setenv("SHELL", "/bin/sh", 1); execl("/bin/sh", profile ? "-sh" : "sh", NULL); warn(_("%s: exec failed"), "/bin/sh"); }
int main(int argc, char **argv) { security_context_t usercon = NULL, cur_context = NULL; char *user = NULL, *level = NULL, *role=NULL, *seuser=NULL, *dlevel=NULL; char *service = NULL; int ret, opt; int verbose = 0; while ((opt = getopt(argc, argv, "l:r:s:v")) > 0) { switch (opt) { case 'l': level = strdup(optarg); break; case 'r': role = strdup(optarg); break; case 's': service = strdup(optarg); break; case 'v': verbose = 1; break; default: usage(argv[0], "invalid option", 1); } } if (((argc - optind) < 1) || ((argc - optind) > 2)) usage(argv[0], "invalid number of arguments", 2); /* If selinux isn't available, bail out. */ if (!is_selinux_enabled()) { fprintf(stderr, "%s may be used only on a SELinux kernel.\n", argv[0]); return 1; } user = argv[optind]; /* If a context wasn't passed, use the current context. */ if (((argc - optind) < 2)) { if (getcon(&cur_context) < 0) { fprintf(stderr, "Couldn't get current context.\n"); return 2; } } else cur_context = argv[optind + 1]; if ((ret = getseuser(user, service, &seuser, &dlevel)) == 0) { if (! level) level=dlevel; if (role != NULL && role[0]) ret=get_default_context_with_rolelevel(seuser, role, level,cur_context,&usercon); else ret=get_default_context_with_level(seuser, level, cur_context,&usercon); } if (ret < 0) perror(argv[0]); else { if (verbose) { printf("%s: %s from %s %s %s %s -> %s\n", argv[0], user, cur_context, seuser, role, level, usercon); } else { printf("%s\n", usercon); } } free(role); free(seuser); if (level != dlevel) free(level); free(dlevel); free(usercon); return ret >= 0; }