summaryrefslogtreecommitdiffstats
path: root/login-utils
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:26:14 +0100
committerKarel Zak2006-12-07 00:26:14 +0100
commitd03dd60840f0a08464d5266539ad356aefe24b03 (patch)
tree0a9ad240a7a88eb6b11b152974a7a51a0df79b75 /login-utils
parentImported from util-linux-2.12pre tarball. (diff)
downloadkernel-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/Makefile19
-rw-r--r--login-utils/chfn.c27
-rw-r--r--login-utils/chsh.c27
-rw-r--r--login-utils/login.c21
-rw-r--r--login-utils/selinux_utils.c55
-rw-r--r--login-utils/selinux_utils.h2
-rw-r--r--login-utils/vipw.c24
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) {