All of lore.kernel.org
 help / color / mirror / Atom feed
* getseuserbyname patch
@ 2005-09-27 18:25 Daniel J Walsh
  2005-09-28 16:39 ` Stephen Smalley
  0 siblings, 1 reply; 18+ messages in thread
From: Daniel J Walsh @ 2005-09-27 18:25 UTC (permalink / raw)
  To: SELinux

[-- Attachment #1: Type: text/plain, Size: 1066 bytes --]

Currently applied to libsetrans, since we have come to no conclusion on 
where this should go.

Currently takes a file of the format
cat /etc/selinux/seusers.conf
dwalsh:staff_u:s0-s0:c1,c5
pwalsh:user_u::   #This is an error
rwalsh:user_u:s4
root:staff_u:s0-s0-s0:c0,c127
default:user_u:s0

Currently I placed the flat file in /etc/selinux/ directory, but might 
be better off in the policy directory, since s4 or staff_u might not be 
defined for MCS policy.

Eventually this function will call out to LDAP also, so not a good 
candidate for libselinux, unless we want the ls command linking against 
LDAP.

I want to add this function to login programs (Pam, gdm) in order to 
limit MCS users.

Need to figure out what to do if no entries are returned.  (I guess 
allow policy to decide.)  Maybe we should eliminate default entry?

Function returns structure containing

username
seusername
sensitivity (Could be a range)
Categories.(Can be null).

When you call selinux functions you will need to create a level by 
appending Sensitivity + ":" + Categories

Dan

[-- Attachment #2: diff --]
[-- Type: text/plain, Size: 8468 bytes --]

diff -r -uN libsetrans-0.1.7/include/Makefile libsetrans-0.1.8/include/Makefile
--- libsetrans-0.1.7/include/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ libsetrans-0.1.8/include/Makefile	2005-09-27 12:22:56.000000000 -0400
@@ -0,0 +1,12 @@
+# Installation directories.
+PREFIX ?= $(DESTDIR)/usr
+INCDIR ?= $(PREFIX)/include/selinux
+
+install:
+	test -d $(INCDIR) || install -m 755 -d $(INCDIR)
+	install -m 644 $(wildcard selinux/*.h) $(INCDIR)
+
+clean: 
+	-rm -f *~ \#*
+	-rm -f selinux/*~ selinux/\#*
+
diff -r -uN libsetrans-0.1.7/include/selinux/seuser.h libsetrans-0.1.8/include/selinux/seuser.h
--- libsetrans-0.1.7/include/selinux/seuser.h	1969-12-31 19:00:00.000000000 -0500
+++ libsetrans-0.1.8/include/selinux/seuser.h	2005-09-27 11:42:31.000000000 -0400
@@ -0,0 +1,32 @@
+#ifndef _SEUSER_H_
+#define _SEUSER_H_
+
+#include <sys/types.h>
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define SEUSERFILE "/etc/selinux/seusers.conf"
+
+/* Define data structures */
+typedef struct seuser {
+	char* username;
+	char* seusername;
+	char* sensitivity;
+	char* categories;
+} seuser_t;
+
+/* read /etc/selinux/seusers.conf file an return selinux user info */
+
+extern void free_seuser(seuser_t *seuser);
+
+extern int getseuserbyname(const char *name, seuser_t **r_seuser);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -r -uN libsetrans-0.1.7/Makefile libsetrans-0.1.8/Makefile
--- libsetrans-0.1.7/Makefile	2005-09-20 21:48:42.000000000 -0400
+++ libsetrans-0.1.8/Makefile	2005-09-27 12:21:21.000000000 -0400
@@ -3,6 +3,7 @@
 	$(MAKE) -C utils
 
 install: 
+	$(MAKE) -C include install
 	$(MAKE) -C src install
 	$(MAKE) -C utils install
 	$(MAKE) -C man install
@@ -10,6 +11,10 @@
 
 clean:
 	rm -f *~ \#*
+	$(MAKE) -C include clean
 	$(MAKE) -C src clean
 	$(MAKE) -C utils clean
+	$(MAKE) -C man clean
+	$(MAKE) -C scripts clean
+
 
diff -r -uN libsetrans-0.1.7/man/Makefile libsetrans-0.1.8/man/Makefile
--- libsetrans-0.1.7/man/Makefile	2005-09-08 09:36:19.000000000 -0400
+++ libsetrans-0.1.8/man/Makefile	2005-09-27 12:24:28.000000000 -0400
@@ -5,3 +5,6 @@
 	mkdir -p $(MAN8DIR)
 	install -m 644 man8/*.8 $(MAN8DIR)
 
+clean:
+	-rm -f *~ \#*
+	-rm -f man8/*~ man8/\#*
diff -r -uN libsetrans-0.1.7/scripts/Makefile libsetrans-0.1.8/scripts/Makefile
--- libsetrans-0.1.7/scripts/Makefile	2005-09-20 21:47:34.000000000 -0400
+++ libsetrans-0.1.8/scripts/Makefile	2005-09-27 12:23:50.000000000 -0400
@@ -13,5 +13,5 @@
 	install -m 644 chcat.8 $(MANDIR)/man8/
 
 clean:
-	rm -f *~
+	-rm -f *~ \#*
 
diff -r -uN libsetrans-0.1.7/src/dso.h libsetrans-0.1.8/src/dso.h
--- libsetrans-0.1.7/src/dso.h	1969-12-31 19:00:00.000000000 -0500
+++ libsetrans-0.1.8/src/dso.h	2005-09-27 14:15:22.000000000 -0400
@@ -0,0 +1,23 @@
+#ifndef _SEUSER_DSO_H
+#define _SEUSER_DSO_H	1
+
+#ifdef SHARED
+# define hidden __attribute__ ((visibility ("hidden")))
+# define hidden_proto(fct) __hidden_proto (fct, fct##_internal)
+# define __hidden_proto(fct, internal)	\
+     extern __typeof (fct) internal;	\
+     extern __typeof (fct) fct __asm (#internal) hidden;
+# if defined(__alpha__) || defined(__mips__)
+#  define hidden_def(fct) \
+     asm (".globl " #fct "\n" #fct " = " #fct "_internal");
+# else
+#  define hidden_def(fct) \
+     asm (".globl " #fct "\n.set " #fct ", " #fct "_internal");
+#endif
+#else
+# define hidden
+# define hidden_proto(fct)
+# define hidden_def(fct)
+#endif
+
+#endif
diff -r -uN libsetrans-0.1.7/src/setrans.c libsetrans-0.1.8/src/setrans.c
--- libsetrans-0.1.7/src/setrans.c	2005-09-19 13:30:27.000000000 -0400
+++ libsetrans-0.1.8/src/setrans.c	2005-09-27 13:44:58.000000000 -0400
@@ -6,6 +6,7 @@
 #include <ctype.h>
 #include <selinux/selinux.h>
 #include <selinux/context.h>
+#include "dso.h"
 
 #define CATEGORYFILE "/etc/mcs.conf"
 
@@ -24,7 +25,7 @@
 static cat_t *catlist=NULL;
 
 /* Remove excess white space */
-static char *strtrim(char *dest, char *source, int size) {
+char * strtrim(char *dest, char *source, int size) {
 	int i=0;
 	char *ptr=source;
 	i=0;
@@ -40,6 +41,7 @@
 	return dest;
 }
 
+hidden_proto(strtrim)
 void finish_context_translations(void) {
 	cat_t *ptr=NULL;
 	cat_t *current=NULL;
diff -r -uN libsetrans-0.1.7/src/seusers.c libsetrans-0.1.8/src/seusers.c
--- libsetrans-0.1.7/src/seusers.c	1969-12-31 19:00:00.000000000 -0500
+++ libsetrans-0.1.8/src/seusers.c	2005-09-27 14:16:58.000000000 -0400
@@ -0,0 +1,140 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+#include <selinux/seuser.h>
+#include "dso.h"
+
+extern char* hidden strtrim(char *dest, char *source, int size);
+void free_seuser(seuser_t *seuser) {
+	if (!seuser) return;
+	if (seuser->username)
+		free(seuser->username);
+	if (seuser->seusername)
+		free(seuser->seusername);
+	if (seuser->sensitivity)
+		free(seuser->sensitivity);
+	if (seuser->categories)
+		free(seuser->categories);
+	free(seuser);
+	return;
+}
+
+/* Process line from SEUSERSFILE. 
+   Remove white space and set name do data before the "=" and sename to data
+   after it */
+static int process_seusers(const char *buffer, seuser_t **r_user) {
+	char name[BUFSIZ];
+	char name1[BUFSIZ];
+	seuser_t *user=NULL;
+	char *ptr;
+	int rc=-1;
+	char *tok;
+	char *newbuf=strdup(buffer);
+	if (!newbuf) return -1;
+
+	user=calloc(1, sizeof(seuser_t));
+	if (!user) return -1;
+
+	tok=strtok_r(newbuf,":",&ptr);
+	if (!tok) goto err;
+	strncpy(name1,tok, sizeof(name1)-1);
+	strtrim(name,name1,sizeof(name)-1);
+	if ( name[0]=='#' ) goto err;
+	user->username=strdup(name);
+	if (!user->username) {
+		free_seuser(user);
+		rc=-1; 
+		goto err;
+	}
+
+	tok=strtok_r(NULL,":",&ptr);
+	if (!tok) goto err;
+	while (isspace(*tok)) tok++;
+	strncpy(name1,tok, sizeof(name1)-1);
+	strtrim(name,name1,sizeof(name)-1);
+	if(strlen(name))
+	   user->seusername=strdup(name);
+	if (!user->seusername) {
+		free_seuser(user);
+		rc=-1; 
+		goto err;
+	}
+
+	tok=strtok_r(NULL,":",&ptr);
+	if (!tok) goto err;
+	while (isspace(*tok)) tok++;
+	strncpy(name1,tok, sizeof(name1)-1);
+	strtrim(name,name1,sizeof(name)-1);
+	if(strlen(name))
+	   user->sensitivity=strdup(name);
+	if (!user->sensitivity) {
+		free_seuser(user);
+		rc=-1; 
+		goto err;
+	}
+
+	tok=strtok_r(NULL,":",&ptr);
+	if (tok) {
+		while (isspace(*tok)) tok++;
+		strncpy(name1,tok, sizeof(name1)-1);
+		strtrim(name,name1,sizeof(name)-1);
+		if(strlen(name))
+		   user->categories=strdup(name);
+		if (!user->categories) {
+			free_seuser(user);
+			rc=-1; 
+			goto err;
+		}
+	}
+
+	*r_user=user;
+	rc=0;
+err:		
+	free(newbuf);
+	return rc;
+}
+
+int getseuserbyname(const char *name, seuser_t **r_seuser) {
+	FILE *cfg=NULL;
+	size_t size=0;
+	char *buffer=NULL;
+
+        static seuser_t *seuser=NULL;
+        static seuser_t *defaultseuser=NULL;
+
+	cfg = fopen(SEUSERFILE,"r");
+	if (!cfg) return -1;
+
+	while (getline(&buffer, &size, cfg) > 0) {
+		if(process_seusers(buffer, &seuser) == 0) {
+			if (strcasecmp(seuser->username, name)==0) 
+			    break;
+
+			if (strcasecmp(seuser->username,"default")==0) {
+				if (defaultseuser) 	free_seuser(defaultseuser);
+				defaultseuser=seuser;
+			} 
+			else 
+				free_seuser(seuser);
+			seuser=NULL;
+		}
+	}
+	if (buffer) free(buffer);
+	fclose(cfg);
+	if (seuser) {
+		free_seuser(defaultseuser);
+		*r_seuser=seuser;
+		return 0;
+	}
+	if (defaultseuser) {
+		*r_seuser=defaultseuser;
+		return 0;
+	}
+		
+	return -1;
+}
diff -r -uN libsetrans-0.1.7/utils/getseuser.c libsetrans-0.1.8/utils/getseuser.c
--- libsetrans-0.1.7/utils/getseuser.c	1969-12-31 19:00:00.000000000 -0500
+++ libsetrans-0.1.8/utils/getseuser.c	2005-09-27 11:49:09.000000000 -0400
@@ -0,0 +1,31 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <errno.h>
+#include <string.h>
+#include <selinux/seuser.h>
+
+void usage(const char *progname) 
+{
+	fprintf(stderr, "usage:  %s\n", progname);
+	exit(1);
+}
+int main(int argc, char **argv) {
+	seuser_t *seuser;
+	if ( argc != 2 ) usage(argv[0]);
+	if (getseuserbyname(argv[1], &seuser) == 0 ) {
+		printf("%s\n", seuser->username);
+		printf("%s\n", seuser->seusername);
+		printf("%s", seuser->sensitivity);
+		if (seuser->categories) 
+			printf(":%s\n", seuser->categories);
+		else
+			printf("\n");
+		free_seuser(seuser);
+		return 0;
+	} else {
+		printf("%s not found\n", argv[1]);
+		return -1;
+	}
+}

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-09-27 18:25 getseuserbyname patch Daniel J Walsh
@ 2005-09-28 16:39 ` Stephen Smalley
  2005-09-29 13:24   ` Daniel J Walsh
  0 siblings, 1 reply; 18+ messages in thread
From: Stephen Smalley @ 2005-09-28 16:39 UTC (permalink / raw)
  To: Daniel J Walsh; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

On Tue, 2005-09-27 at 14:25 -0400, Daniel J Walsh wrote:
> Currently applied to libsetrans, since we have come to no conclusion on 
> where this should go.

I still view that as a mistake; libsetrans is about translating between
kernel security contexts and human-readable security labels,
particularly for MCS/MLS where we expect them to differ, is completely
unnecessary in the non-MCS/MLS case, and is brought in by all libselinux
users when context translations are enabled.  Mapping Linux users to
SELinux users (and, in the MCS/MLS case, a MLS range) is something we
want regardless of whether context translations are performed, and needs
to be done by login-type apps only.

> Currently takes a file of the format
> cat /etc/selinux/seusers.conf
> dwalsh:staff_u:s0-s0:c1,c5
> pwalsh:user_u::   #This is an error
> rwalsh:user_u:s4
> root:staff_u:s0-s0-s0:c0,c127

Isn't this an error too?

> default:user_u:s0
> 
> Currently I placed the flat file in /etc/selinux/ directory, but might 
> be better off in the policy directory, since s4 or staff_u might not be 
> defined for MCS policy.

Right, it contains policy-specific data.  On the other hand, we expect
to offload it to an LDAP directory, so it will ultimately live entirely
outside of the policy-specific directory.

> Eventually this function will call out to LDAP also, so not a good 
> candidate for libselinux, unless we want the ls command linking against 
> LDAP.

Putting it into libsetrans yields the same effect, because ls depends on
libselinux which dlopen's libsetrans whenever it exists, right?  The
best option would be to create yet another library for it.  However, if
that is strongly disliked, I'd say just put it directly into libselinux.
libselinux can certainly defer dlopen/dlsym of ldap or any other backend
library until it actually needs the backend, so that we don't pick them
up for ls.

> I want to add this function to login programs (Pam, gdm) in order to 
> limit MCS users.

More generally, to let us authorize Linux users for SELinux role sets
(via the indirection of SELinux users) and (in the MCS/MLS case)
particular ranges without needing to add them individually to the
policy.

> Need to figure out what to do if no entries are returned.  (I guess 
> allow policy to decide.)  Maybe we should eliminate default entry?

The issue there is that if your config provides no default user and
range, and you pass the Linux username along to libselinux, it will try
that user but then fallback internally to user_u and whatever the kernel
provides for a range.  And user_u will likely be authorized for the full
range in the kernel policy since you are now using this new
configuration to restrict what categories are accessible to individual
Linux users.

> Function returns structure containing
> 
> username
> seusername
> sensitivity (Could be a range)
> Categories.(Can be null).
> 
> When you call selinux functions you will need to create a level by 
> appending Sensitivity + ":" + Categories

No, you just want to take the Linux username as the input parameter, and
return the SELinux username and the entire range string as a whole, then
pass that to libselinux.  The low level can have a category set too,
e.g. s0:c1-s0:c1,c2.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-09-28 16:39 ` Stephen Smalley
@ 2005-09-29 13:24   ` Daniel J Walsh
  2005-09-29 13:35     ` Stephen Smalley
  2005-09-29 15:10     ` Stephen Smalley
  0 siblings, 2 replies; 18+ messages in thread
From: Daniel J Walsh @ 2005-09-29 13:24 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

[-- Attachment #1: Type: text/plain, Size: 195 bytes --]

Updated patch for libselinux.

I have a couple of questions?

Is s0:c1-s0:c2  a valid range?  Is s0:c1-s0:c1,c2 implied or required?

Can this range read/write s0 files in MCS?  MLS?

Dan

-- 



[-- Attachment #2: libselinux-rhat.patch --]
[-- Type: text/x-patch, Size: 6013 bytes --]

diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/selinux.h libselinux-1.27.1/include/selinux/selinux.h
--- nsalibselinux/include/selinux/selinux.h	2005-09-01 11:17:40.000000000 -0400
+++ libselinux-1.27.1/include/selinux/selinux.h	2005-09-28 14:37:04.000000000 -0400
@@ -354,6 +354,25 @@
 extern int selinux_raw_to_trans_context(security_context_t raw, 
 					security_context_t *transp);
 
+
+/* the following functions are used to retrieve the SELinux user and their 
+   security level via the  Linux usernames selinux */
+
+#define SEUSERFILE "/etc/selinux/seusers.conf"
+
+/* Define data structures */
+typedef struct seuser {
+	char* username;
+	char* seusername;
+	char* level;
+} seuser_t;
+
+/* read /etc/selinux/seusers.conf file an return selinux user info */
+
+extern void freeseuser(seuser_t *seuser);
+
+extern int getseuserbyname(const char *name, seuser_t **r_seuser);
+
 #ifdef __cplusplus
 }
 #endif
diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/seuser.h libselinux-1.27.1/include/selinux/seuser.h
--- nsalibselinux/include/selinux/seuser.h	1969-12-31 19:00:00.000000000 -0500
+++ libselinux-1.27.1/include/selinux/seuser.h	2005-09-28 14:32:11.000000000 -0400
@@ -0,0 +1,32 @@
+#ifndef _SEUSER_H_
+#define _SEUSER_H_
+
+#include <sys/types.h>
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define SEUSERFILE "/etc/selinux/seusers.conf"
+
+/* Define data structures */
+typedef struct seuser {
+	char* username;
+	char* seusername;
+	char* sensitivity;
+	char* categories;
+} seuser_t;
+
+/* read /etc/selinux/seusers.conf file an return selinux user info */
+
+extern void free_seuser(seuser_t *seuser);
+
+extern int getseuserbyname(const char *name, seuser_t **r_seuser);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --exclude-from=exclude -N -u -r nsalibselinux/man/Makefile libselinux-1.27.1/man/Makefile
--- nsalibselinux/man/Makefile	2004-10-20 16:31:36.000000000 -0400
+++ libselinux-1.27.1/man/Makefile	2005-09-28 14:32:16.000000000 -0400
@@ -8,3 +8,6 @@
 	install -m 644 man3/*.3 $(MAN3DIR)
 	install -m 644 man8/*.8 $(MAN8DIR)
 
+clean:
+	-rm -f *~ \#*
+	-rm -f man8/*~ man8/\#*
diff --exclude-from=exclude -N -u -r nsalibselinux/src/seusers.c libselinux-1.27.1/src/seusers.c
--- nsalibselinux/src/seusers.c	1969-12-31 19:00:00.000000000 -0500
+++ libselinux-1.27.1/src/seusers.c	2005-09-28 14:48:28.000000000 -0400
@@ -0,0 +1,132 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+#include "selinux_internal.h"
+
+void freeseuser(seuser_t *seuser) {
+	if (!seuser) return;
+	if (seuser->username)
+		free(seuser->username);
+	if (seuser->seusername)
+		free(seuser->seusername);
+	if (seuser->level)
+		free(seuser->level);
+	free(seuser);
+	return;
+}
+
+/* Process line from SEUSERSFILE. 
+   Remove white space and set name do data before the "=" and sename to data
+   after it */
+static int process_seusers(const char *buffer, seuser_t **r_user) {
+	seuser_t *user=NULL;
+	char *ptr;
+	int rc=-1;
+	char *tok;
+	char *newbuf=strdup(buffer);
+	if (!newbuf) return -1;
+
+	user=calloc(1, sizeof(seuser_t));
+	if (!user) return -1;
+
+	tok=strtok_r(newbuf,":",&ptr);
+	if (!tok) goto err;
+	if ( tok[0]=='#' ) goto err;
+	user->username=strdup(tok);
+	if (!user->username) {
+		freeseuser(user);
+		rc=-1; 
+		goto err;
+	}
+
+	tok=strtok_r(NULL,":",&ptr);
+	if (!tok) goto err;
+	while (isspace(*tok)) tok++;
+	if(strlen(tok))
+	   user->seusername=strdup(tok);
+	if (!user->seusername) {
+		freeseuser(user);
+		rc=-1; 
+		goto err;
+	}
+
+	tok=strtok_r(NULL,":",&ptr);
+	if (!tok) goto err;
+	while (isspace(*tok)) tok++;
+	if(strlen(tok))
+	   user->level=strdup(tok);
+	if (!user->level) {
+		freeseuser(user);
+		rc=-1; 
+		goto err;
+	}
+
+	tok=strtok_r(NULL,":",&ptr);
+	if (tok) {
+		int len;
+		while (isspace(*tok)) tok++;
+		len=strlen(tok);
+		if(len) {
+			char *ptr=realloc(user->level, strlen(user->level) + len + 2);
+			if (ptr==NULL) {
+				freeseuser(user);
+				rc=-1; 
+				goto err;
+			}
+			user->level=ptr;
+			strcat(user->level,":");
+			strcat(user->level,tok);
+		}
+	}
+
+	*r_user=user;
+	rc=0;
+err:		
+	free(newbuf);
+	return rc;
+}
+
+int getseuserbyname(const char *name, seuser_t **r_seuser) {
+	FILE *cfg=NULL;
+	size_t size=0;
+	char *buffer=NULL;
+
+        static seuser_t *seuser=NULL;
+        static seuser_t *defaultseuser=NULL;
+
+	cfg = fopen(SEUSERFILE,"r");
+	if (!cfg) return -1;
+
+	while (getline(&buffer, &size, cfg) > 0) {
+		if(process_seusers(buffer, &seuser) == 0) {
+			if (strcasecmp(seuser->username, name)==0) 
+			    break;
+
+			if (strcasecmp(seuser->username,"default")==0) {
+				if (defaultseuser) 	freeseuser(defaultseuser);
+				defaultseuser=seuser;
+			} 
+			else 
+				freeseuser(seuser);
+			seuser=NULL;
+		}
+	}
+	if (buffer) free(buffer);
+	fclose(cfg);
+	if (seuser) {
+		freeseuser(defaultseuser);
+		*r_seuser=seuser;
+		return 0;
+	}
+	if (defaultseuser) {
+		*r_seuser=defaultseuser;
+		return 0;
+	}
+		
+	return -1;
+}
diff --exclude-from=exclude -N -u -r nsalibselinux/utils/getseuser.c libselinux-1.27.1/utils/getseuser.c
--- nsalibselinux/utils/getseuser.c	1969-12-31 19:00:00.000000000 -0500
+++ libselinux-1.27.1/utils/getseuser.c	2005-09-28 14:49:21.000000000 -0400
@@ -0,0 +1,27 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <errno.h>
+#include <string.h>
+#include <selinux/selinux.h>
+
+void usage(const char *progname) 
+{
+	fprintf(stderr, "usage:  %s\n", progname);
+	exit(1);
+}
+int main(int argc, char **argv) {
+	seuser_t *seuser;
+	if ( argc != 2 ) usage(argv[0]);
+	if (getseuserbyname(argv[1], &seuser) == 0 ) {
+		printf("%s\n", seuser->username);
+		printf("%s\n", seuser->seusername);
+		printf("%s", seuser->level);
+		freeseuser(seuser);
+		return 0;
+	} else {
+		printf("%s not found\n", argv[1]);
+		return -1;
+	}
+}

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-09-29 13:24   ` Daniel J Walsh
@ 2005-09-29 13:35     ` Stephen Smalley
  2005-09-29 15:10     ` Stephen Smalley
  1 sibling, 0 replies; 18+ messages in thread
From: Stephen Smalley @ 2005-09-29 13:35 UTC (permalink / raw)
  To: Daniel J Walsh; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

On Thu, 2005-09-29 at 09:24 -0400, Daniel J Walsh wrote:
> Is s0:c1-s0:c2  a valid range?  Is s0:c1-s0:c1,c2 implied or required?

No, the first one is not valid.  You have to explicitly specify the
latter (s0:c1-s0:c1,c2) or the kernel will reject it because the high
won't dominate the low and the high does not implicitly inherit
categories from the low.

> Can this range read/write s0 files in MCS?  MLS?

>From the constraint definitions in the MCS policy, it appears that MCS
would allow such a process to read/write s0 files, because its high
level dominates the file level.  But I would never expect such a process
to exist under MCS, as MCS wants processes to run with a low level of s0
at all times so that any files they create default to s0 as well.

For MLS, such a process could read a s0 file (since it dominates the
file level), but could not write a s0 file (because of the "no write
down" restriction, to prevent leaking the category data to s0).

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-09-29 13:24   ` Daniel J Walsh
  2005-09-29 13:35     ` Stephen Smalley
@ 2005-09-29 15:10     ` Stephen Smalley
  2005-09-29 15:23       ` Daniel J Walsh
  1 sibling, 1 reply; 18+ messages in thread
From: Stephen Smalley @ 2005-09-29 15:10 UTC (permalink / raw)
  To: Daniel J Walsh; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

On Thu, 2005-09-29 at 09:24 -0400, Daniel J Walsh wrote:
> Updated patch for libselinux.

diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/selinux.h libselinux-1.27.1/include/selinux/selinux.h
--- nsalibselinux/include/selinux/selinux.h	2005-09-01 11:17:40.000000000 -0400
+++ libselinux-1.27.1/include/selinux/selinux.h	2005-09-28 14:37:04.000000000 -0400
@@ -354,6 +354,25 @@
 extern int selinux_raw_to_trans_context(security_context_t raw, 
 					security_context_t *transp);
 
+
+/* the following functions are used to retrieve the SELinux user and their 
+   security level via the  Linux usernames selinux */
+
+#define SEUSERFILE "/etc/selinux/seusers.conf"
+
+/* Define data structures */
+typedef struct seuser {
+	char* username;
+	char* seusername;
+	char* level;
+} seuser_t;
+
+/* read /etc/selinux/seusers.conf file an return selinux user info */
+
+extern void freeseuser(seuser_t *seuser);
+
+extern int getseuserbyname(const char *name, seuser_t **r_seuser);
+

Why not just:
extern int getseuserbyname(const char *linuxname, char **seusername, char **selevel);

Why do we need the struct?  Even with the struct, why do we need to return the
(Linux) username since it was provided by the caller in the first place?
Seems simpler to just omit the struct from the public interface.

Also, the config file location doesn't need to be exported in the header;
it should be private to libselinux.  

diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/seuser.h libselinux-1.27.1/include/selinux/seuser.h
--- nsalibselinux/include/selinux/seuser.h	1969-12-31 19:00:00.000000000 -0500
+++ libselinux-1.27.1/include/selinux/seuser.h	2005-09-28 14:32:11.000000000 -0400

This looks like the old interface.  Leftover file that should be dropped?

diff --exclude-from=exclude -N -u -r nsalibselinux/src/seusers.c libselinux-1.27.1/src/seusers.c
--- nsalibselinux/src/seusers.c	1969-12-31 19:00:00.000000000 -0500
+++ libselinux-1.27.1/src/seusers.c	2005-09-28 14:48:28.000000000 -0400
@@ -0,0 +1,132 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+#include "selinux_internal.h"
+
+void freeseuser(seuser_t *seuser) {
+	if (!seuser) return;
+	if (seuser->username)
+		free(seuser->username);
+	if (seuser->seusername)
+		free(seuser->seusername);
+	if (seuser->level)
+		free(seuser->level);

You don't need the if statements for the component frees, because
free(NULL) is legitimate and does no harm.

+	while (getline(&buffer, &size, cfg) > 0) {
+		if(process_seusers(buffer, &seuser) == 0) {
+			if (strcasecmp(seuser->username, name)==0) 
+			    break;

Why case-insensitive comparison?  Are 'root' and 'Root' really identical as far 
as the rest of the system is concerned?

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-09-29 15:23       ` Daniel J Walsh
@ 2005-09-29 15:20         ` Stephen Smalley
  2005-09-29 19:11         ` Daniel J Walsh
  1 sibling, 0 replies; 18+ messages in thread
From: Stephen Smalley @ 2005-09-29 15:20 UTC (permalink / raw)
  To: Daniel J Walsh; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

On Thu, 2005-09-29 at 11:23 -0400, Daniel J Walsh wrote:
> I was mimicking getpwdbyname.  Also this allows the user to see if he 
> got default instead of username.

getpwnam returns a lot more information, so it makes more sense there.
I'm not sure how the caller would make use of knowing that he matched
the default record rather than a specific record.

> Finally we have the ability to add additional fields in the future, if 
> we ever need them without breaking API.

Changing an exported structure still breaks the _ABI_, which is just as
important for a shared library.  So it doesn't buy you anything unless
you hide the struct definition and force them to use get/set methods to
get and set the individual fields (see Ivan's patches for examples).  At
which point you have to ask whether it is worth the more complicated
interface in this case versus just providing the strings directly, since
you never pass this struct back into libselinux anywhere.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-09-29 15:10     ` Stephen Smalley
@ 2005-09-29 15:23       ` Daniel J Walsh
  2005-09-29 15:20         ` Stephen Smalley
  2005-09-29 19:11         ` Daniel J Walsh
  0 siblings, 2 replies; 18+ messages in thread
From: Daniel J Walsh @ 2005-09-29 15:23 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

Stephen Smalley wrote:

>On Thu, 2005-09-29 at 09:24 -0400, Daniel J Walsh wrote:
>  
>
>>Updated patch for libselinux.
>>    
>>
>
>diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/selinux.h libselinux-1.27.1/include/selinux/selinux.h
>--- nsalibselinux/include/selinux/selinux.h	2005-09-01 11:17:40.000000000 -0400
>+++ libselinux-1.27.1/include/selinux/selinux.h	2005-09-28 14:37:04.000000000 -0400
>@@ -354,6 +354,25 @@
> extern int selinux_raw_to_trans_context(security_context_t raw, 
> 					security_context_t *transp);
> 
>+
>+/* the following functions are used to retrieve the SELinux user and their 
>+   security level via the  Linux usernames selinux */
>+
>+#define SEUSERFILE "/etc/selinux/seusers.conf"
>+
>+/* Define data structures */
>+typedef struct seuser {
>+	char* username;
>+	char* seusername;
>+	char* level;
>+} seuser_t;
>+
>+/* read /etc/selinux/seusers.conf file an return selinux user info */
>+
>+extern void freeseuser(seuser_t *seuser);
>+
>+extern int getseuserbyname(const char *name, seuser_t **r_seuser);
>+
>
>Why not just:
>extern int getseuserbyname(const char *linuxname, char **seusername, char **selevel);
>
>Why do we need the struct?  Even with the struct, why do we need to return the
>(Linux) username since it was provided by the caller in the first place?
>Seems simpler to just omit the struct from the public interface.
>
>  
>
I was mimicking getpwdbyname.  Also this allows the user to see if he 
got default instead of username.

Finally we have the ability to add additional fields in the future, if 
we ever need them without breaking API.

>Also, the config file location doesn't need to be exported in the header;
>it should be private to libselinux.  
>
>  
>
Ok.

>diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/seuser.h libselinux-1.27.1/include/selinux/seuser.h
>--- nsalibselinux/include/selinux/seuser.h	1969-12-31 19:00:00.000000000 -0500
>+++ libselinux-1.27.1/include/selinux/seuser.h	2005-09-28 14:32:11.000000000 -0400
>
>This looks like the old interface.  Leftover file that should be dropped?
>
>diff --exclude-from=exclude -N -u -r nsalibselinux/src/seusers.c libselinux-1.27.1/src/seusers.c
>--- nsalibselinux/src/seusers.c	1969-12-31 19:00:00.000000000 -0500
>+++ libselinux-1.27.1/src/seusers.c	2005-09-28 14:48:28.000000000 -0400
>@@ -0,0 +1,132 @@
>+#include <unistd.h>
>+#include <fcntl.h>
>+#include <stdlib.h>
>+#include <string.h>
>+#include <stdio.h>
>+#include <ctype.h>
>+#include <selinux/selinux.h>
>+#include <selinux/context.h>
>+#include "selinux_internal.h"
>+
>+void freeseuser(seuser_t *seuser) {
>+	if (!seuser) return;
>+	if (seuser->username)
>+		free(seuser->username);
>+	if (seuser->seusername)
>+		free(seuser->seusername);
>+	if (seuser->level)
>+		free(seuser->level);
>
>You don't need the if statements for the component frees, because
>free(NULL) is legitimate and does no harm.
>
>+	while (getline(&buffer, &size, cfg) > 0) {
>+		if(process_seusers(buffer, &seuser) == 0) {
>+			if (strcasecmp(seuser->username, name)==0) 
>+			    break;
>
>Why case-insensitive comparison?  Are 'root' and 'Root' really identical as far 
>as the rest of the system is concerned?
>
>  
>

Agreed this should not be strcasecmp.

-- 



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-09-29 15:23       ` Daniel J Walsh
  2005-09-29 15:20         ` Stephen Smalley
@ 2005-09-29 19:11         ` Daniel J Walsh
  2005-09-29 21:21           ` Stephen Smalley
  1 sibling, 1 reply; 18+ messages in thread
From: Daniel J Walsh @ 2005-09-29 19:11 UTC (permalink / raw)
  To: Daniel J Walsh
  Cc: Stephen Smalley, Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan,
	SELinux

[-- Attachment #1: Type: text/plain, Size: 96 bytes --]

Ok lets try again.

getseuserbyname(const char *username, char **seuser, char **level);


-- 



[-- Attachment #2: libselinux-rhat.patch --]
[-- Type: text/x-patch, Size: 7515 bytes --]

diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/selinux.h libselinux-1.27.1/include/selinux/selinux.h
--- nsalibselinux/include/selinux/selinux.h	2005-09-01 11:17:40.000000000 -0400
+++ libselinux-1.27.1/include/selinux/selinux.h	2005-09-29 14:46:48.000000000 -0400
@@ -323,6 +323,7 @@
 extern const char *selinux_booleans_path(void);
 extern const char *selinux_customizable_types_path(void);
 extern const char *selinux_users_path(void);
+extern const char *selinux_usersconf_path(void);
 
 /* Check a permission in the passwd class.
    Return 0 if granted or -1 otherwise. */
@@ -354,6 +355,12 @@
 extern int selinux_raw_to_trans_context(security_context_t raw, 
 					security_context_t *transp);
 
+
+/* the following functions are used to retrieve the SELinux user and their 
+   security level via the  Linux usernames selinux */
+
+extern int getseuserbyname(const char *name, char **seuser, char **level);
+
 #ifdef __cplusplus
 }
 #endif
diff --exclude-from=exclude -N -u -r nsalibselinux/man/Makefile libselinux-1.27.1/man/Makefile
--- nsalibselinux/man/Makefile	2004-10-20 16:31:36.000000000 -0400
+++ libselinux-1.27.1/man/Makefile	2005-09-28 14:32:16.000000000 -0400
@@ -8,3 +8,6 @@
 	install -m 644 man3/*.3 $(MAN3DIR)
 	install -m 644 man8/*.8 $(MAN8DIR)
 
+clean:
+	-rm -f *~ \#*
+	-rm -f man8/*~ man8/\#*
diff --exclude-from=exclude -N -u -r nsalibselinux/man/man3/getseuserbyname.3 libselinux-1.27.1/man/man3/getseuserbyname.3
--- nsalibselinux/man/man3/getseuserbyname.3	1969-12-31 19:00:00.000000000 -0500
+++ libselinux-1.27.1/man/man3/getseuserbyname.3	2005-09-29 15:09:57.000000000 -0400
@@ -0,0 +1,21 @@
+.TH "getseuserbyname" "3" "29 September 2005" "dwalsh@redhat.com" "SE Linux API documentation"
+.SH "NAME"
+getseuserbyname \- get SELinux user and level via Linux username
+.SH "SYNOPSIS"
+.B #include <selinux/selinux.h>
+.sp
+.BI "int getseuserbyname(const char *" username ", char **" selinuxuser ", char **" level ");
+.SH "DESCRIPTION"
+.B getseuserbyname
+retrieves the SELinux Username and security level associated with username.
+
+.br
+
+The returned SELinux username and level should be free with free if non-NULL.  
+.SH "RETURN VALUE"
+On success, 0 is returned indicating.
+On failure, \-1 is returned and errno is set appropriately.
+
+The errors documented for the stat(2) system call are also applicable
+here.
+
diff --exclude-from=exclude -N -u -r nsalibselinux/src/selinux_config.c libselinux-1.27.1/src/selinux_config.c
--- nsalibselinux/src/selinux_config.c	2005-03-17 14:56:21.000000000 -0500
+++ libselinux-1.27.1/src/selinux_config.c	2005-09-29 11:28:55.000000000 -0400
@@ -11,6 +11,7 @@
 
 #define SELINUXDIR "/etc/selinux/"
 #define SELINUXCONFIG SELINUXDIR "config"
+#define SELINUXUSERS SELINUXDIR "seusers.conf"
 #define SELINUXDEFAULT "targeted"
 #define SELINUXTYPETAG "SELINUXTYPE="
 #define SELINUXTAG "SELINUX="
@@ -252,5 +253,9 @@
 const char *selinux_users_path() {
   return get_path(USERS_DIR);
 }
+const char *selinux_usersconf_path() {
+  return SELINUXUSERS;
+}
+
 hidden_def(selinux_users_path)
 
diff --exclude-from=exclude -N -u -r nsalibselinux/src/selinux_internal.h libselinux-1.27.1/src/selinux_internal.h
--- nsalibselinux/src/selinux_internal.h	2005-08-25 16:18:01.000000000 -0400
+++ libselinux-1.27.1/src/selinux_internal.h	2005-09-29 14:49:43.000000000 -0400
@@ -49,6 +49,7 @@
 hidden_proto(selinux_check_passwd_access)
 hidden_proto(matchpathcon_init)
 hidden_proto(selinux_users_path)
+hidden_proto(selinux_usersconf_path);
 
 extern int context_translations hidden;
 extern int hidden trans_to_raw_context(char *trans, char **rawp);
diff --exclude-from=exclude -N -u -r nsalibselinux/src/seusers.c libselinux-1.27.1/src/seusers.c
--- nsalibselinux/src/seusers.c	1969-12-31 19:00:00.000000000 -0500
+++ libselinux-1.27.1/src/seusers.c	2005-09-29 14:51:47.000000000 -0400
@@ -0,0 +1,138 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+#include "selinux_internal.h"
+
+/* Process line from seusers.conf. 
+   Remove white space and set name do data before the "=" and sename to data
+   after it */
+static int process_seusers(const char *buffer, char **r_username, char **r_seuser, char **r_level) {
+	char *username=NULL;
+	char *seuser=NULL;
+	char *level=NULL;
+	char *ptr;
+	int rc=-1;
+	char *tok;
+	char *newbuf=strdup(buffer);
+	if (!newbuf) return -1;
+
+	tok=strtok_r(newbuf,":",&ptr);
+	if (!tok) goto err;
+	if ( tok[0]=='#' ) goto err;
+	username=strdup(tok);
+	if (!username) {
+		rc=-1; 
+		goto err;
+	}
+
+	tok=strtok_r(NULL,":",&ptr);
+	if (!tok) goto err;
+	while (isspace(*tok)) tok++;
+	if(strlen(tok))
+	   seuser=strdup(tok);
+	if (!seuser) {
+		free(username);
+		rc=-1; 
+		goto err;
+	}
+
+	tok=strtok_r(NULL,":",&ptr);
+	if (!tok) goto err;
+	while (isspace(*tok)) tok++;
+	if(strlen(tok))
+		level=strdup(tok);
+	if (!level) {
+		free(username);
+		free(seuser);
+		rc=-1; 
+		goto err;
+	}
+
+	tok=strtok_r(NULL,":",&ptr);
+	if (tok) {
+		int len;
+		while (isspace(*tok)) tok++;
+		len=strlen(tok);
+		if(len) {
+			char *ptr=realloc(level, strlen(level) + len + 2);
+			if (ptr==NULL) {
+				free(username);
+				free(seuser);
+				free(level);
+				rc=-1; 
+				goto err;
+			}
+			level=ptr;
+			strcat(level,":");
+			strcat(level,tok);
+		}
+	}
+
+	*r_username=username;
+	*r_seuser=seuser;
+	*r_level=level;
+	rc=0;
+err:		
+	free(newbuf);
+	return rc;
+}
+
+int getseuserbyname(const char *name, char **r_seuser, char **r_level) {
+	FILE *cfg=NULL;
+	size_t size=0;
+	char *buffer=NULL;
+
+	char *username=NULL;
+        char *seuser=NULL;
+        char *level=NULL;
+        char *defaultseuser=NULL;
+        char *defaultlevel=NULL;
+
+	cfg = fopen(selinux_usersconf_path(),"r");
+	if (!cfg) return -1;
+
+	while (getline(&buffer, &size, cfg) > 0) {
+		if(process_seusers(buffer, &username, &seuser, &level) == 0) {
+			if (strcmp(username, name)==0) 
+			    break;
+
+			if (strcmp(username,"default")==0) {
+				free(username);
+				if (defaultseuser) 
+					free(defaultseuser);
+				if (defaultlevel) 
+					free(defaultlevel);
+				defaultseuser=seuser;
+				defaultlevel=level;
+			} 
+			else {
+				free(username);
+				free(seuser);
+				free(level);
+			}
+			seuser=NULL;
+		}
+	}
+	if (buffer) free(buffer);
+	fclose(cfg);
+	if (seuser) {
+		free(username);
+		free(defaultseuser);
+		free(defaultlevel);
+		*r_seuser=seuser;
+		*r_level=level;
+		return 0;
+	}
+	if (defaultseuser) {
+		*r_seuser=defaultseuser;
+		*r_level=defaultlevel;
+		return 0;
+	}
+		
+	return -1;
+}
diff --exclude-from=exclude -N -u -r nsalibselinux/utils/getseuser.c libselinux-1.27.1/utils/getseuser.c
--- nsalibselinux/utils/getseuser.c	1969-12-31 19:00:00.000000000 -0500
+++ libselinux-1.27.1/utils/getseuser.c	2005-09-29 14:46:06.000000000 -0400
@@ -0,0 +1,27 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <errno.h>
+#include <string.h>
+#include <selinux/selinux.h>
+
+void usage(const char *progname) 
+{
+	fprintf(stderr, "usage:  %s\n", progname);
+	exit(1);
+}
+int main(int argc, char **argv) {
+	char *seuser;
+	char *level;
+	if ( argc != 2 ) usage(argv[0]);
+	if (getseuserbyname(argv[1], &seuser, &level) == 0 ) {
+		printf("%s\n", argv[1]);
+		printf("%s\n", seuser);
+		printf("%s", level);
+		return 0;
+	} else {
+		printf("%s not found\n", argv[1]);
+		return -1;
+	}
+}

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-09-29 19:11         ` Daniel J Walsh
@ 2005-09-29 21:21           ` Stephen Smalley
  2005-10-03 15:52             ` Stephen Smalley
  0 siblings, 1 reply; 18+ messages in thread
From: Stephen Smalley @ 2005-09-29 21:21 UTC (permalink / raw)
  To: Daniel J Walsh; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

On Thu, 2005-09-29 at 15:11 -0400, Daniel J Walsh wrote:
> Ok lets try again.
> 
> getseuserbyname(const char *username, char **seuser, char **level);

I think this interface is good to go, so you can proceed to work with
it.  I still need to go through the implementation carefully prior to
merging it upstream.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-09-29 21:21           ` Stephen Smalley
@ 2005-10-03 15:52             ` Stephen Smalley
  2005-10-03 16:29               ` Stephen Smalley
  0 siblings, 1 reply; 18+ messages in thread
From: Stephen Smalley @ 2005-10-03 15:52 UTC (permalink / raw)
  To: Daniel J Walsh; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

On Thu, 2005-09-29 at 17:21 -0400, Stephen Smalley wrote:
> On Thu, 2005-09-29 at 15:11 -0400, Daniel J Walsh wrote:
> > Ok lets try again.
> > 
> > getseuserbyname(const char *username, char **seuser, char **level);
> 
> I think this interface is good to go, so you can proceed to work with
> it.  I still need to go through the implementation carefully prior to
> merging it upstream.

I merged a revised implementation of this interface into libselinux
1.27.2, as you know.  However, it occurred to me that if you are going
to rework pam_selinux and the SELinux patches for sshd, crond, etc to
use this interface along with either get_ordered_context_list_with_level
or get_default_context_with_level, then we need to make sure this also
works when using a non-MLS policy.  The simplest approach would be to
have getseuserbyname not require (but allow) a MLS field in the config
file if MLS is disabled (!is_selinux_mls_enabled()), and just set *level
to NULL in that case.  get_ordered_context_list_with_level and
get_default_context_with_level will handle that correctly already.  The
caller can still unconditionally free the level afterward as free (NULL)
is perfectly valid and harmless.

This will ensure that the same code will work regardless of whether MLS
is enabled or not, and that people can still use seusers.conf to map
Linux users to SELinux users (and thus to role sets) even in the non-MLS
case.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-10-03 15:52             ` Stephen Smalley
@ 2005-10-03 16:29               ` Stephen Smalley
  2005-10-06 13:16                 ` Stephen Smalley
  0 siblings, 1 reply; 18+ messages in thread
From: Stephen Smalley @ 2005-10-03 16:29 UTC (permalink / raw)
  To: Daniel J Walsh; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

[-- Attachment #1: Type: text/plain, Size: 2409 bytes --]

On Mon, 2005-10-03 at 11:52 -0400, Stephen Smalley wrote:
> I merged a revised implementation of this interface into libselinux
> 1.27.2, as you know.  However, it occurred to me that if you are going
> to rework pam_selinux and the SELinux patches for sshd, crond, etc to
> use this interface along with either get_ordered_context_list_with_level
> or get_default_context_with_level, then we need to make sure this also
> works when using a non-MLS policy.  The simplest approach would be to
> have getseuserbyname not require (but allow) a MLS field in the config
> file if MLS is disabled (!is_selinux_mls_enabled()), and just set *level
> to NULL in that case.  get_ordered_context_list_with_level and
> get_default_context_with_level will handle that correctly already.  The
> caller can still unconditionally free the level afterward as free (NULL)
> is perfectly valid and harmless.
> 
> This will ensure that the same code will work regardless of whether MLS
> is enabled or not, and that people can still use seusers.conf to map
> Linux users to SELinux users (and thus to role sets) even in the non-MLS
> case.

Patch below makes this change.  Next question is error handling in
either getseuserbyname() itself or in the caller, given that you are
converting pam_selinux and the SELinux patches to always call this
function.  If seusers.conf doesn't exist, getseuserbyname() could simply
set the *seuser to the linuxuser, set the *level to NULL and return
success to the caller, so that the caller would then call
get*_with_level with the Linux user and a NULL level, and that function
in turn would devolve to the normal get* call with the Linux user.  That
would provide equivalence to the current behavior if seusers.conf
doesn't exist on the system.  Downside is that if seusers.conf were
accidentally "lost", user might end up gaining greater access than
desired because user_u might be authorized for all categories in the
kernel policy.  Similar issue exists if seusers.conf exists but contains
no default entry and no matching entry for the Linux user, as you
mentioned earlier.  Possibly /etc/selinux/config should specify whether
user mapping is enabled or disabled explicitly?  Then getseuserbyname
could use that to determine whether it should just fall back to the
Linux user and NULL level always, or try accessing seusers.conf.
Thoughts?

-- 
Stephen Smalley
National Security Agency

[-- Attachment #2: libselinux-seuser-nomls.patch --]
[-- Type: text/x-patch, Size: 1827 bytes --]

Index: libselinux/src/seusers.c
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/seusers.c,v
retrieving revision 1.2
diff -u -p -r1.2 seusers.c
--- libselinux/src/seusers.c	30 Sep 2005 18:37:54 -0000	1.2
+++ libselinux/src/seusers.c	3 Oct 2005 15:53:54 -0000
@@ -13,7 +13,8 @@
 static int process_seusers(const char *buffer, 
 			   char **luserp, 
 			   char **seuserp, 
-			   char **levelp)
+			   char **levelp,
+			   int mls_enabled)
 {
 	char *newbuf = strdup(buffer);
 	char *luser = NULL, *seuser = NULL, *level = NULL;
@@ -40,14 +41,23 @@ static int process_seusers(const char *b
 
 	start = end+1;
 	end = strchr(start, ':');
-	if (!end)
-		goto err;
+	if (!end) {
+		if (mls_enabled)
+			goto err; /* no MLS level and MLS is enabled */
+		/* MLS is disabled, so :level suffix not required. */
+		end = start;
+		while (*end && !isspace(*end))
+			end++;
+	}
 	*end = 0;
 	
 	seuser = strdup(start);
 	if (!seuser)
 		goto err;
 
+	if (!mls_enabled)
+		goto out; /* skip any MLS level */
+
 	start = ++end;
 	while (*end && !isspace(*end))
 		end++;
@@ -57,6 +67,7 @@ static int process_seusers(const char *b
 	if (!level)
 		goto err;
 
+out:
 	free(newbuf);
 	*luserp = luser;
 	*seuserp = seuser;
@@ -76,6 +87,7 @@ int getseuserbyname(const char *name, ch
 	char *buffer=NULL;
 	int rc;
 	unsigned long lineno = 0;
+	int mls_enabled = is_selinux_mls_enabled();
 
 	char *username=NULL;
         char *seuser=NULL;
@@ -89,7 +101,7 @@ int getseuserbyname(const char *name, ch
 
 	while (getline(&buffer, &size, cfg) > 0) {
 		++lineno;
-		rc = process_seusers(buffer, &username, &seuser, &level);
+		rc = process_seusers(buffer, &username, &seuser, &level, mls_enabled);
 		if (rc == -1)
 			continue; /* comment, skip */
 		if (rc == -2) {

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-10-03 16:29               ` Stephen Smalley
@ 2005-10-06 13:16                 ` Stephen Smalley
  2005-10-06 13:27                   ` Daniel J Walsh
  0 siblings, 1 reply; 18+ messages in thread
From: Stephen Smalley @ 2005-10-06 13:16 UTC (permalink / raw)
  To: Daniel J Walsh; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

On Mon, 2005-10-03 at 12:29 -0400, Stephen Smalley wrote:
> Next question is error handling in
> either getseuserbyname() itself or in the caller, given that you are
> converting pam_selinux and the SELinux patches to always call this
> function.  If seusers.conf doesn't exist, getseuserbyname() could simply
> set the *seuser to the linuxuser, set the *level to NULL and return
> success to the caller, so that the caller would then call
> get*_with_level with the Linux user and a NULL level, and that function
> in turn would devolve to the normal get* call with the Linux user.  That
> would provide equivalence to the current behavior if seusers.conf
> doesn't exist on the system.  Downside is that if seusers.conf were
> accidentally "lost", user might end up gaining greater access than
> desired because user_u might be authorized for all categories in the
> kernel policy.  Similar issue exists if seusers.conf exists but contains
> no default entry and no matching entry for the Linux user, as you
> mentioned earlier.  Possibly /etc/selinux/config should specify whether
> user mapping is enabled or disabled explicitly?  Then getseuserbyname
> could use that to determine whether it should just fall back to the
> Linux user and NULL level always, or try accessing seusers.conf.
> Thoughts?

Any thoughts on this issue?  I just added support for the optional
SETLOCALDEFS= definition (defaults to 1, preserving current logic for
setting local users and booleans) in /etc/selinux/config to libselinux
for the new load policy logic, so I could also add support for an
optional REQUIRESEUSERS= definition (defaulting to 0) to it.  Then, if
the definition is set to 1, and /etc/seusers.conf doesn't exist,
getseuserbyname will return an error as it currently does; otherwise, it
will just set *seuser to a copy of the linuxuser and set the level to
NULL so that we end up with no change in behavior when not using
seusers.conf.  Of course, someone will ultimately need to update
system-config-securitylevel to deal with these additional settings.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-10-06 13:16                 ` Stephen Smalley
@ 2005-10-06 13:27                   ` Daniel J Walsh
  2005-10-06 13:38                     ` Stephen Smalley
  0 siblings, 1 reply; 18+ messages in thread
From: Daniel J Walsh @ 2005-10-06 13:27 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

Stephen Smalley wrote:
> On Mon, 2005-10-03 at 12:29 -0400, Stephen Smalley wrote:
>   
>> Next question is error handling in
>> either getseuserbyname() itself or in the caller, given that you are
>> converting pam_selinux and the SELinux patches to always call this
>> function.  If seusers.conf doesn't exist, getseuserbyname() could simply
>> set the *seuser to the linuxuser, set the *level to NULL and return
>> success to the caller, so that the caller would then call
>> get*_with_level with the Linux user and a NULL level, and that function
>> in turn would devolve to the normal get* call with the Linux user.  That
>> would provide equivalence to the current behavior if seusers.conf
>> doesn't exist on the system.  Downside is that if seusers.conf were
>> accidentally "lost", user might end up gaining greater access than
>> desired because user_u might be authorized for all categories in the
>> kernel policy.  Similar issue exists if seusers.conf exists but contains
>> no default entry and no matching entry for the Linux user, as you
>> mentioned earlier.  Possibly /etc/selinux/config should specify whether
>> user mapping is enabled or disabled explicitly?  Then getseuserbyname
>> could use that to determine whether it should just fall back to the
>> Linux user and NULL level always, or try accessing seusers.conf.
>> Thoughts?
>>     
>
> Any thoughts on this issue?  I just added support for the optional
> SETLOCALDEFS= definition (defaults to 1, preserving current logic for
> setting local users and booleans) in /etc/selinux/config to libselinux
> for the new load policy logic, so I could also add support for an
> optional REQUIRESEUSERS= definition (defaulting to 0) to it.  Then, if
> the definition is set to 1, and /etc/seusers.conf doesn't exist,
> getseuserbyname will return an error as it currently does; otherwise, it
> will just set *seuser to a copy of the linuxuser and set the level to
> NULL so that we end up with no change in behavior when not using
> seusers.conf.  Of course, someone will ultimately need to update
> system-config-securitylevel to deal with these additional settings.
>
>   
A couple of things I was thinking about.  

1.  The call should be to just return the username and level "" if the 
file does not exist or if there is not default value and no match.  So 
the only time the call would return an error was if no memory.

2. The file should be put into a policy specific directories and be 
shipped with the policy.  When we move to LDAP, we will require a policy 
type in the key for retrieving users.  This way we can continue to allow 
users to switch from one type of policy to another.




-- 



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-10-06 13:27                   ` Daniel J Walsh
@ 2005-10-06 13:38                     ` Stephen Smalley
  2005-10-06 13:52                       ` Daniel J Walsh
  0 siblings, 1 reply; 18+ messages in thread
From: Stephen Smalley @ 2005-10-06 13:38 UTC (permalink / raw)
  To: Daniel J Walsh; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

On Thu, 2005-10-06 at 09:27 -0400, Daniel J Walsh wrote:
> A couple of things I was thinking about.  
> 
> 1.  The call should be to just return the username and level "" if the 
> file does not exist or if there is not default value and no match.  So 
> the only time the call would return an error was if no memory.

The problem with always doing this is that it could lead to insecurity,
e.g. accidental (or malicious) removal of seusers.conf or filesystem
corruption could end up allowing the user to login with a much greater
level of access than desired, because we will be using seusers.conf to
control the authorized categories for individual Linux users rather than
the kernel policy.  That's why I suggested making it a configurable
setting in /etc/selinux/config, so that we have the option of treating
it as an error condition that prevents login rather than falling back.
For MCS or MLS, I think we would actually want to make it an error
condition and require the presence of seusers.conf and a default entry.
For existing systems (e.g. FC4) and any system that doesn't want/need a
separate user mapping, we'd leave it as a non-error condition so that
nothing breaks there.  Note btw that it is *level = NULL that we want,
so that get_ordered_context_with_level and
get_default_context_with_level fall back to the ordinary functions.

> 2. The file should be put into a policy specific directories and be 
> shipped with the policy.  When we move to LDAP, we will require a policy 
> type in the key for retrieving users.  This way we can continue to allow 
> users to switch from one type of policy to another.

That's ok, as long as you are fine with the notion that some files in
the policy package can be customized by the user.  If you want the
policy package to ultimately become "pristine" files shipped by the
distributor and keep all user customizations separate, then it seems
like it needs to go in a separate package, much as /etc/passwd et al are
in their own special setup package.  It would be nice if ultimately rpm
-V selinux-policy-targeted (or strict) would report no changes from mere
local customizations.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-10-06 13:38                     ` Stephen Smalley
@ 2005-10-06 13:52                       ` Daniel J Walsh
  2005-10-06 16:52                         ` Stephen Smalley
  0 siblings, 1 reply; 18+ messages in thread
From: Daniel J Walsh @ 2005-10-06 13:52 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

Stephen Smalley wrote:
> On Thu, 2005-10-06 at 09:27 -0400, Daniel J Walsh wrote:
>   
>> A couple of things I was thinking about.  
>>
>> 1.  The call should be to just return the username and level "" if the 
>> file does not exist or if there is not default value and no match.  So 
>> the only time the call would return an error was if no memory.
>>     
>
> The problem with always doing this is that it could lead to insecurity,
> e.g. accidental (or malicious) removal of seusers.conf or filesystem
> corruption could end up allowing the user to login with a much greater
> level of access than desired, because we will be using seusers.conf to
> control the authorized categories for individual Linux users rather than
> the kernel policy.  That's why I suggested making it a configurable
> setting in /etc/selinux/config, so that we have the option of treating
> it as an error condition that prevents login rather than falling back.
> For MCS or MLS, I think we would actually want to make it an error
> condition and require the presence of seusers.conf and a default entry.
> For existing systems (e.g. FC4) and any system that doesn't want/need a
> separate user mapping, we'd leave it as a non-error condition so that
> nothing breaks there.  Note btw that it is *level = NULL that we want,
> so that get_ordered_context_with_level and
> get_default_context_with_level fall back to the ordinary functions.
>
>   
Of course if I can get rid of this file, I can probably muck around with 
the config file also.   
As long as we don't require the flag and default to old behavior.  For 
MLS installs we can
put in the flag in the config file and change it to fail if the file is 
missing.
>> 2. The file should be put into a policy specific directories and be 
>> shipped with the policy.  When we move to LDAP, we will require a policy 
>> type in the key for retrieving users.  This way we can continue to allow 
>> users to switch from one type of policy to another.
>>     
>
> That's ok, as long as you are fine with the notion that some files in
> the policy package can be customized by the user.  If you want the
> policy package to ultimately become "pristine" files shipped by the
> distributor and keep all user customizations separate, then it seems
> like it needs to go in a separate package, much as /etc/passwd et al are
> in their own special setup package.  It would be nice if ultimately rpm
> -V selinux-policy-targeted (or strict) would report no changes from mere
> local customizations.
>
>   
There are files in policy now that are marked config(noreplace) like 
local.users, ports, devices etc.  So I don't think this is any 
differerent. 

-- 



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-10-06 13:52                       ` Daniel J Walsh
@ 2005-10-06 16:52                         ` Stephen Smalley
  2005-10-06 17:10                           ` Daniel J Walsh
  0 siblings, 1 reply; 18+ messages in thread
From: Stephen Smalley @ 2005-10-06 16:52 UTC (permalink / raw)
  To: Daniel J Walsh; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

On Thu, 2005-10-06 at 09:52 -0400, Daniel J Walsh wrote:
> Of course if I can get rid of this file, I can probably muck around with 
> the config file also.   
> As long as we don't require the flag and default to old behavior.  For 
> MLS installs we can
> put in the flag in the config file and change it to fail if the file is 
> missing.

Yes, that was the idea.

BTW, it occurs to me that the cases are different for no seusers.conf
versus a seusers.conf but no matching entry and no default entry.  The
latter is more dangerous to allow to default to the old behavior,
because a simple error in the config file could cause it to skip the
entry for the user.  Is it unreasonable to always treat no match/no
default as an error?

> There are files in policy now that are marked config(noreplace) like 
> local.users, ports, devices etc.  So I don't think this is any 
> differerent. 

Yes, I just wasn't sure if you ultimately intend to migrate them out,
particularly if libsemanage takes over control of all customizations.
At that point, the files from policy are just pushed into the sandbox
and all modifications occur within the sandbox and to the generated
files used at runtime, not directly to any files from the policy
package.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-10-06 16:52                         ` Stephen Smalley
@ 2005-10-06 17:10                           ` Daniel J Walsh
  2005-10-06 18:33                             ` Stephen Smalley
  0 siblings, 1 reply; 18+ messages in thread
From: Daniel J Walsh @ 2005-10-06 17:10 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

Stephen Smalley wrote:
> On Thu, 2005-10-06 at 09:52 -0400, Daniel J Walsh wrote:
>   
>> Of course if I can get rid of this file, I can probably muck around with 
>> the config file also.   
>> As long as we don't require the flag and default to old behavior.  For 
>> MLS installs we can
>> put in the flag in the config file and change it to fail if the file is 
>> missing.
>>     
>
> Yes, that was the idea.
>
> BTW, it occurs to me that the cases are different for no seusers.conf
> versus a seusers.conf but no matching entry and no default entry.  The
> latter is more dangerous to allow to default to the old behavior,
> because a simple error in the config file could cause it to skip the
> entry for the user.  Is it unreasonable to always treat no match/no
> default as an error?
>
>   
Ok, I was just thinking the level on no match would be SystemLow, but 
that is not easy to state in policy.
So Force there to be a default/match or return error, is ok.
>> There are files in policy now that are marked config(noreplace) like 
>> local.users, ports, devices etc.  So I don't think this is any 
>> differerent. 
>>     
>
> Yes, I just wasn't sure if you ultimately intend to migrate them out,
> particularly if libsemanage takes over control of all customizations.
> At that point, the files from policy are just pushed into the sandbox
> and all modifications occur within the sandbox and to the generated
> files used at runtime, not directly to any files from the policy
> package.
>
>   
But they still will need to exist and be recompiled into the sandbox 
correct?  I would still consider these files to be policy
specific.  So they would need to be in the policy try. 

BTW:  I would like to rename seusers.conf to seusers and put it in 
/etc/selinux/TYPE/seusers

I also am upping sensitivity level to s15 and category to c255, in the 
latest policy and changing the range lines appropriately.
As proposed by Steve Grubb.

As soon as a libselinux changes show up I will put in patch to 
pam_selinux to allow level selection.

-- 



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: getseuserbyname patch
  2005-10-06 17:10                           ` Daniel J Walsh
@ 2005-10-06 18:33                             ` Stephen Smalley
  0 siblings, 0 replies; 18+ messages in thread
From: Stephen Smalley @ 2005-10-06 18:33 UTC (permalink / raw)
  To: Daniel J Walsh; +Cc: Darrel Goeddel, Ivan Gyurdiev, Karl MacMillan, SELinux

[-- Attachment #1: Type: text/plain, Size: 582 bytes --]

On Thu, 2005-10-06 at 13:10 -0400, Daniel J Walsh wrote:
> BTW:  I would like to rename seusers.conf to seusers and put it in 
> /etc/selinux/TYPE/seusers
> 
> I also am upping sensitivity level to s15 and category to c255, in the 
> latest policy and changing the range lines appropriately.
> As proposed by Steve Grubb.
> 
> As soon as a libselinux changes show up I will put in patch to 
> pam_selinux to allow level selection.

Hmm...ok.  Patch below should alter the error handling for no seusers,
and move it under $SELINUXTYPE.


-- 
Stephen Smalley
National Security Agency

[-- Attachment #2: libselinux-1.27.7.patch --]
[-- Type: text/x-patch, Size: 6257 bytes --]

Index: libselinux/ChangeLog
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/ChangeLog,v
retrieving revision 1.148
retrieving revision 1.149
diff -u -p -r1.148 -r1.149
--- libselinux/ChangeLog	6 Oct 2005 16:00:26 -0000	1.148
+++ libselinux/ChangeLog	6 Oct 2005 18:19:32 -0000	1.149
@@ -1,3 +1,9 @@
+1.27.7 2005-10-06
+	* Changed getseuserbyname to fall back to the Linux username and
+	NULL level if seusers config file doesn't exist unless 
+	REQUIRESEUSERS=1 is set in /etc/selinux/config.
+	* Moved seusers.conf under $SELINUXTYPE and renamed to seusers.
+
 1.27.6 2005-10-06
 	* Added selinux_init_load_policy() function as an even higher level
 	interface for the initial policy load by /sbin/init.  This obsoletes
Index: libselinux/VERSION
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/VERSION,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -p -r1.66 -r1.67
--- libselinux/VERSION	6 Oct 2005 16:00:27 -0000	1.66
+++ libselinux/VERSION	6 Oct 2005 18:19:32 -0000	1.67
@@ -1 +1 @@
-1.27.6
+1.27.7
Index: libselinux/src/file_path_suffixes.h
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/file_path_suffixes.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -p -r1.5 -r1.6
--- libselinux/src/file_path_suffixes.h	17 Feb 2005 15:21:06 -0000	1.5
+++ libselinux/src/file_path_suffixes.h	6 Oct 2005 18:19:32 -0000	1.6
@@ -11,3 +11,4 @@ S_(MEDIA_CONTEXTS, "/contexts/files/medi
 S_(REMOVABLE_CONTEXT, "/contexts/removable_context")
 S_(CUSTOMIZABLE_TYPES, "/contexts/customizable_types")
 S_(USERS_DIR, "/users/")
+S_(SEUSERS, "/seusers")
Index: libselinux/src/selinux_config.c
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/selinux_config.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -p -r1.19 -r1.20
--- libselinux/src/selinux_config.c	6 Oct 2005 16:00:27 -0000	1.19
+++ libselinux/src/selinux_config.c	6 Oct 2005 18:19:32 -0000	1.20
@@ -11,11 +11,11 @@
 
 #define SELINUXDIR "/etc/selinux/"
 #define SELINUXCONFIG SELINUXDIR "config"
-#define SELINUXUSERS SELINUXDIR "seusers.conf"
 #define SELINUXDEFAULT "targeted"
 #define SELINUXTYPETAG "SELINUXTYPE="
 #define SELINUXTAG "SELINUX="
 #define SETLOCALDEFS "SETLOCALDEFS="
+#define REQUIRESEUSERS "REQUIRESEUSERS="
 
 /* Indices for file paths arrays. */
 #define BINPOLICY         0
@@ -30,7 +30,8 @@
 #define REMOVABLE_CONTEXT 9
 #define CUSTOMIZABLE_TYPES    10
 #define USERS_DIR         11
-#define NEL               12
+#define SEUSERS           12
+#define NEL               13
 
 /* New layout is relative to SELINUXDIR/policytype. */
 static char *file_paths[NEL];
@@ -121,13 +122,13 @@ hidden_def(selinux_getenforcemode)
 
 static char *selinux_policyroot = NULL;
 
-static void init_selinux_policyroot(void) __attribute__ ((constructor));
+static void init_selinux_config(void) __attribute__ ((constructor));
 
-static void init_selinux_policyroot(void)
+static void init_selinux_config(void)
 {
-  int i;
+  int i, *intptr;
   size_t rootlen, len;
-  char *line_buf = NULL, *buf_p;
+  char *line_buf = NULL, *buf_p, *value;
   FILE *fp;
 
   if (selinux_policyroot) return;
@@ -165,17 +166,25 @@ static void init_selinux_policyroot(void
 				  return;
 			  snprintf(selinux_policyroot, rootlen, "%s%s", 
 				   SELINUXDIR, type);
+			  continue;
 		  } else if (!strncmp(buf_p, SETLOCALDEFS, 
 				      sizeof(SETLOCALDEFS)-1)) {
-			  char *value;
 			  value = buf_p + sizeof(SETLOCALDEFS)-1;
-			  if (isdigit(*value)) 
-				  load_setlocaldefs = atoi(value);
-			  else if (strncasecmp(value, "true", sizeof("true")-1))
-				  load_setlocaldefs = 1;
-			  else if (strncasecmp(value, "false", sizeof("false")-1))
-				  load_setlocaldefs = 0;
+			  intptr = &load_setlocaldefs;
+		  } else if (!strncmp(buf_p, REQUIRESEUSERS, 
+				      sizeof(REQUIRESEUSERS)-1)) {
+			  value = buf_p + sizeof(REQUIRESEUSERS)-1;
+			  intptr = &require_seusers;
+		  } else {
+			  continue;
 		  }
+
+		  if (isdigit(*value)) 
+			  *intptr = atoi(value);
+		  else if (strncasecmp(value, "true", sizeof("true")-1))
+			  *intptr = 1;
+		  else if (strncasecmp(value, "false", sizeof("false")-1))
+			  *intptr = 0;
 	  }
 	  free(line_buf);
 	  fclose(fp);
@@ -281,7 +290,7 @@ const char *selinux_users_path() {
   return get_path(USERS_DIR);
 }
 const char *selinux_usersconf_path() {
-  return SELINUXUSERS;
+  return get_path(SEUSERS);
 }
 
 hidden_def(selinux_users_path)
Index: libselinux/src/selinux_internal.h
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/selinux_internal.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -p -r1.12 -r1.13
--- libselinux/src/selinux_internal.h	6 Oct 2005 16:00:27 -0000	1.12
+++ libselinux/src/selinux_internal.h	6 Oct 2005 18:19:32 -0000	1.13
@@ -65,4 +65,4 @@ extern int hidden trans_to_raw_context(c
 extern int hidden raw_to_trans_context(char *raw, char **transp);
 
 extern int load_setlocaldefs hidden;
-
+extern int require_seusers hidden;
Index: libselinux/src/seusers.c
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/seusers.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -p -r1.3 -r1.4
--- libselinux/src/seusers.c	3 Oct 2005 17:06:16 -0000	1.3
+++ libselinux/src/seusers.c	6 Oct 2005 18:19:33 -0000	1.4
@@ -81,6 +81,8 @@ err:
 	return -2; /* error */
 }
 
+int require_seusers hidden = 0;
+
 int getseuserbyname(const char *name, char **r_seuser, char **r_level) {
 	FILE *cfg=NULL;
 	size_t size=0;
@@ -96,8 +98,16 @@ int getseuserbyname(const char *name, ch
         char *defaultlevel=NULL;
 
 	cfg = fopen(selinux_usersconf_path(), "r");
-	if (!cfg) 
-		return -1;
+	if (!cfg) {
+		if (require_seusers)
+			return -1;
+		/* Fall back to the Linux username and no level. */
+		*r_seuser = strdup(name);
+		if (!(*r_seuser))
+			return -1;
+		*r_level = NULL;
+		return 0;
+	}
 
 	while (getline(&buffer, &size, cfg) > 0) {
 		++lineno;

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2005-10-06 18:33 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-27 18:25 getseuserbyname patch Daniel J Walsh
2005-09-28 16:39 ` Stephen Smalley
2005-09-29 13:24   ` Daniel J Walsh
2005-09-29 13:35     ` Stephen Smalley
2005-09-29 15:10     ` Stephen Smalley
2005-09-29 15:23       ` Daniel J Walsh
2005-09-29 15:20         ` Stephen Smalley
2005-09-29 19:11         ` Daniel J Walsh
2005-09-29 21:21           ` Stephen Smalley
2005-10-03 15:52             ` Stephen Smalley
2005-10-03 16:29               ` Stephen Smalley
2005-10-06 13:16                 ` Stephen Smalley
2005-10-06 13:27                   ` Daniel J Walsh
2005-10-06 13:38                     ` Stephen Smalley
2005-10-06 13:52                       ` Daniel J Walsh
2005-10-06 16:52                         ` Stephen Smalley
2005-10-06 17:10                           ` Daniel J Walsh
2005-10-06 18:33                             ` Stephen Smalley

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.