diff options
author | Karel Zak | 2006-12-07 00:26:14 +0100 |
---|---|---|
committer | Karel Zak | 2006-12-07 00:26:14 +0100 |
commit | d03dd60840f0a08464d5266539ad356aefe24b03 (patch) | |
tree | 0a9ad240a7a88eb6b11b152974a7a51a0df79b75 /login-utils | |
parent | Imported from util-linux-2.12pre tarball. (diff) | |
download | kernel-qcow2-util-linux-d03dd60840f0a08464d5266539ad356aefe24b03.tar.gz kernel-qcow2-util-linux-d03dd60840f0a08464d5266539ad356aefe24b03.tar.xz kernel-qcow2-util-linux-d03dd60840f0a08464d5266539ad356aefe24b03.zip |
Imported from util-linux-2.12a tarball.
Diffstat (limited to 'login-utils')
-rw-r--r-- | login-utils/Makefile | 19 | ||||
-rw-r--r-- | login-utils/chfn.c | 27 | ||||
-rw-r--r-- | login-utils/chsh.c | 27 | ||||
-rw-r--r-- | login-utils/login.c | 21 | ||||
-rw-r--r-- | login-utils/selinux_utils.c | 55 | ||||
-rw-r--r-- | login-utils/selinux_utils.h | 2 | ||||
-rw-r--r-- | login-utils/vipw.c | 24 |
7 files changed, 159 insertions, 16 deletions
diff --git a/login-utils/Makefile b/login-utils/Makefile index 13191a4a2..baefa434c 100644 --- a/login-utils/Makefile +++ b/login-utils/Makefile @@ -48,6 +48,12 @@ PAM=-lpam -ldl -lpam_misc PAMFL=-DUSE_PAM=1 endif +ifeq "$(HAVE_SELINUX)" "yes" +CFLAGS += -DWITH_SELINUX=1 -g +SELINUXLLIB=-lselinux +SELINUXOBJS=selinux_utils.o +endif + ifeq "$(HAVE_SHADOW)" "no" ifeq "$(HAVE_PAM)" "no" ifeq "$(HAVE_PASSWD)" "no" @@ -96,18 +102,18 @@ shutdown.o simpleinit.o: $(LIB)/linux_reboot.h wall.o: ttymsg.h $(LIB)/carefulputc.h agetty: agetty.o $(LIB)/xstrncpy.o -chfn: chfn.o islocal.o setpwnam.o $(LIB)/env.o $(LIB)/xstrncpy.o - $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM) -chsh: chsh.o islocal.o setpwnam.o $(LIB)/env.o - $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM) +chfn: chfn.o islocal.o setpwnam.o $(SELINUXOBJS) $(LIB)/env.o $(LIB)/xstrncpy.o + $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM) $(SELINUXLLIB) +chsh: chsh.o islocal.o setpwnam.o $(SELINUXOBJS) $(LIB)/env.o + $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM) $(SELINUXLLIB) last: last.o ifeq "$(HAVE_PAM)" "yes" login: login.o $(LIB)/setproctitle.o $(LIB)/xstrncpy.o - $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM) + $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM) $(SELINUXLLIB) else login: login.o $(LIB)/xstrncpy.o $(LIB)/setproctitle.o checktty.o - $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) + $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(SELINUXLLIB) endif mesg: mesg.o $(ERR_O) @@ -124,6 +130,7 @@ initctl: initctl.o $(CC) $(LDFLAGS) -o $@ $^ vipw: vipw.o $(LIB)/xstrncpy.o + $(CC) $(LDFLAGS) -o $@ $^ $(SELINUXLLIB) newgrp.o: $(LIB)/pathnames.h $(CC) -c $(CFLAGS) $(PAMFL) newgrp.c diff --git a/login-utils/chfn.c b/login-utils/chfn.c index 7c6bfac05..643a16319 100644 --- a/login-utils/chfn.c +++ b/login-utils/chfn.c @@ -40,6 +40,12 @@ #include "nls.h" #include "env.h" +#ifdef WITH_SELINUX +#include <selinux/selinux.h> +#include <selinux/av_permissions.h> +#include "selinux_utils.h" +#endif + #if REQUIRE_PASSWORD && USE_PAM #include <security/pam_appl.h> #include <security/pam_misc.h> @@ -136,6 +142,27 @@ int main (int argc, char **argv) { exit(1); } +#ifdef WITH_SELINUX + if (is_selinux_enabled()) { + if(uid == 0) { + if (checkAccess(oldf.username,PASSWD__CHFN)!=0) { + security_context_t user_context; + if (getprevcon(&user_context) < 0) + user_context=(security_context_t) strdup(_("Unknown user context")); + fprintf(stderr, _("%s: %s is not authorized to change the finger info of %s\n"), + whoami, user_context, oldf.username); + freecon(user_context); + exit(1); + } + } + if (setupDefaultContext("/etc/passwd") != 0) { + fprintf(stderr,_("%s: Can't set default context for /etc/passwd"), + whoami); + exit(1); + } + } +#endif + /* Reality check */ if (uid != 0 && uid != oldf.pw->pw_uid) { errno = EACCES; diff --git a/login-utils/chsh.c b/login-utils/chsh.c index ce8c2ae90..8d8f8862e 100644 --- a/login-utils/chsh.c +++ b/login-utils/chsh.c @@ -47,6 +47,12 @@ #include <security/pam_misc.h> #endif +#ifdef WITH_SELINUX +#include <selinux/selinux.h> +#include <selinux/av_permissions.h> +#include "selinux_utils.h" +#endif + typedef unsigned char boolean; #define false 0 #define true 1 @@ -121,6 +127,27 @@ main (int argc, char *argv[]) { exit(1); } +#ifdef WITH_SELINUX + if (is_selinux_enabled()) { + if(uid == 0) { + if (checkAccess(pw->pw_name,PASSWD__CHSH)!=0) { + security_context_t user_context; + if (getprevcon(&user_context) < 0) + user_context=(security_context_t) strdup(_("Unknown user context")); + fprintf(stderr, _("%s: %s is not authorized to change the shell of %s\n"), + whoami, user_context, pw->pw_name); + freecon(user_context); + exit(1); + } + } + if (setupDefaultContext("/etc/passwd") != 0) { + fprintf(stderr,_("%s: Can't set default context for /etc/passwd"), + whoami); + exit(1); + } + } +#endif + oldshell = pw->pw_shell; if (!oldshell[0]) oldshell = "/bin/sh"; diff --git a/login-utils/login.c b/login-utils/login.c index da9b72fde..3b1bfa56e 100644 --- a/login-utils/login.c +++ b/login-utils/login.c @@ -906,9 +906,8 @@ Michael Riepe <michael@stud.uni-hannover.de> if (utp == NULL) { setutent(); ut.ut_type = LOGIN_PROCESS; - strncpy(ut.ut_id, tty_number, sizeof(ut.ut_id)); strncpy(ut.ut_line, tty_name, sizeof(ut.ut_line)); - utp = getutid(&ut); + utp = getutline(&ut); } if (utp) { @@ -1363,15 +1362,17 @@ dolastlog(int quiet) { if (!quiet) { if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) && ll.ll_time != 0) { - printf(_("Last login: %.*s "), - 24-5, (char *)ctime(&ll.ll_time)); + time_t ll_time = (time_t) ll.ll_time; + + printf(_("Last login: %.*s "), + 24-5, ctime(&ll_time)); - if (*ll.ll_host != '\0') - printf(_("from %.*s\n"), - (int)sizeof(ll.ll_host), ll.ll_host); - else - printf(_("on %.*s\n"), - (int)sizeof(ll.ll_line), ll.ll_line); + if (*ll.ll_host != '\0') + printf(_("from %.*s\n"), + (int)sizeof(ll.ll_host), ll.ll_host); + else + printf(_("on %.*s\n"), + (int)sizeof(ll.ll_line), ll.ll_line); } lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET); } diff --git a/login-utils/selinux_utils.c b/login-utils/selinux_utils.c new file mode 100644 index 000000000..3711a632c --- /dev/null +++ b/login-utils/selinux_utils.c @@ -0,0 +1,55 @@ +#ifdef WITH_SELINUX +#include <sys/types.h> +#include <stdio.h> +#include <selinux/selinux.h> +#include <selinux/flask.h> +#include <selinux/av_permissions.h> +#include <selinux/context.h> +#include "selinux_utils.h" + +int checkAccess(char *chuser, int access) { + int status=-1; + security_context_t user_context; + char *user=NULL; + if( getprevcon(&user_context)==0 ) { + context_t c=context_new(user_context); + user=context_user_get(c); + if (strcmp(chuser, user) == 0) { + status=0; + } else { + struct av_decision avd; + int retval = security_compute_av(user_context, + user_context, + SECCLASS_PASSWD, + access, + &avd); + + if ((retval == 0) && + ((access & avd.allowed) == access)) { + status=0; + } + } + context_free(c); + freecon(user_context); + } + return status; +} + +int setupDefaultContext(char *orig_file) { + if (is_selinux_enabled()) { + security_context_t scontext; + + if (getfilecon(orig_file,&scontext)<0) { + return 1; + } + + if (setfscreatecon(scontext) < 0) + { + freecon(scontext); + return 1; + } + freecon(scontext); + } + return 0; +} +#endif diff --git a/login-utils/selinux_utils.h b/login-utils/selinux_utils.h new file mode 100644 index 000000000..5bf393c17 --- /dev/null +++ b/login-utils/selinux_utils.h @@ -0,0 +1,2 @@ +extern int checkAccess(char *name,int access); +extern int setupDefaultContext(char *orig_file); diff --git a/login-utils/vipw.c b/login-utils/vipw.c index cb4048070..22f87428e 100644 --- a/login-utils/vipw.c +++ b/login-utils/vipw.c @@ -67,6 +67,10 @@ static char version_string[] = "vipw 1.4"; #include "xstrncpy.h" #include "nls.h" +#ifdef WITH_SELINUX +#include <selinux/selinux.h> +#endif + #define FILENAMELEN 67 char *progname; @@ -189,6 +193,24 @@ pw_unlock(void) { sprintf(tmp, "%s%s", orig_file, ".OLD"); unlink(tmp); link(orig_file, tmp); + +#ifdef WITH_SELINUX + if (is_selinux_enabled()) { + security_context_t passwd_context=NULL; + int ret=0; + if (getfilecon(orig_file,&passwd_context) < 0) { + (void) fprintf(stderr,_("%s: Can't get context for %s"),progname,orig_file); + pw_error(orig_file, 1, 1); + } + ret=setfilecon(tmp_file,passwd_context); + freecon(passwd_context); + if (ret!=0) { + (void) fprintf(stderr,_("%s: Can't set context for %s"),progname,tmp_file); + pw_error(tmp_file, 1, 1); + } + } +#endif + if (rename(tmp_file, orig_file) == -1) { int errsv = errno; fprintf(stderr, @@ -266,7 +288,9 @@ edit_file(int is_shadow) if (stat(tmp_file, &begin)) pw_error(tmp_file, 1, 1); + pw_edit(0); + if (stat(tmp_file, &end)) pw_error(tmp_file, 1, 1); if (begin.st_mtime == end.st_mtime) { |