[comp.databases] Restricting access to Informix tables

news@investor.UUCP ( Bob Peirce) (05/06/89)

We have a database we want to keep most people from updating or
inserting except under controlled circumstances; ie, No from sperform,
but YES from a 4GL data entry program.  We thought having the data entry
program suid the database manager would do it but no luck.  Apparently
Informix looks at the real user, not the effective user.

Does anybody have a solution?  We want to keep the current lack of
priviliges and get the permission through the 4GL program somehow.
We do not want to actually change permissions from the 4GL program,
however.
-- 
Bob Peirce, Pittsburgh, PA				 412-471-5320
uucp: ...!{allegra, bellcore, cadre, idis, psuvax1}!pitt!investor!rbp
	    NOTE:  Mail must be < 30K  bytes/message

jon@altos86.UUCP (Jonathan Ma) (05/10/89)

In article <1080@investor.UUCP> news@investor.UUCP ( Bob Peirce) writes:
>We have a database we want to keep most people from updating or
>inserting except under controlled circumstances; ie, No from sperform,
>but YES from a 4GL data entry program.  
>-- 
>Bob Peirce, Pittsburgh, PA				 412-471-5320
	You can do the following as root:
	% cd $INFORMIXDIR/bin
	% chmod 500 sperform

	Just a suggestion. Please don't reply or follow-up.

    -Jon-

	UUCP:	{sun,pyramid,amdahl}!altos86!jon
	Disclaimer: those views are mine alone, not my employers'.

aland@infmx.UUCP (Dr. Scump) (05/16/89)

In article <1092@altos86.UUCP> jon@altos86.UUCP (Jonathan Ma) writes:
>In article <1080@investor.UUCP> news@investor.UUCP ( Bob Peirce) writes:
>>We have a database we want to keep most people from updating or
>>inserting except under controlled circumstances; ie, No from sperform,
>>but YES from a 4GL data entry program.  
>>-- 
>>Bob Peirce, Pittsburgh, PA				 412-471-5320
>	You can do the following as root:
>	% cd $INFORMIXDIR/bin
>	% chmod 500 sperform
>
>	Just a suggestion. Please don't reply or follow-up.
>    -Jon-  UUCP:	{sun,pyramid,amdahl}!altos86!jon

Sorry, Jon, but this not a good idea.  Even in 2.10.00 and earlier 
versions, this would prevent ALL users from running ANY forms.
In 2.10.03, things get worse: since "sperform" is just a link to 
the "isql" executable (in UNIX), you would have just prevented
all users from using any ISQL module (compiling or running any forms,
reports, queries, or user menus).

The only way to get the desired functionality that I know of (in UNIX)
is to create a "phony" generic user name for the application,
grant it the appropriate database permissions, make it the program 
owner, and use setuid().

As I see it, a better route would be to be able to grant permissions
to *applications*, like "Application Plans" in DB2.

--
    Alan S. Denney  @  Informix Software, Inc.    
         {pyramid|uunet}!infmx!aland                 "I want to live!
   --------------------------------------------       as an honest man,
    Disclaimer:  These opinions are mine alone.       to get all I deserve
    If I am caught or killed, the secretary           and to give all I can."
    will disavow any knowledge of my actions.             - S. Vega

jim@tiamat.fsc.com (Jim O'Connor) (05/16/89)

In article <1092@altos86.UUCP>, jon@altos86.UUCP (Jonathan Ma) writes:
> In article <1080@investor.UUCP> news@investor.UUCP ( Bob Peirce) writes:
> >We have a database we want to keep most people from updating or
> >inserting except under controlled circumstances; ie, No from sperform,
> >but YES from a 4GL data entry program.  
> 	You can do the following as root:
> 	% cd $INFORMIXDIR/bin
> 	% chmod 500 sperform

This will only keep the users from being able to USE sperform.  This is not
what the original question asked.  We have run into the same problem, and have
come up with a workable solution by using lots of "noadd" and "noupdate"
attributes in the Perform source for the screens the users will use.

There is still another problem, though.  Users who know how, can still run
"isql" and enter random SQL statements to modify the data in the tables.
You can't keep them from running "isql" since "sperform" is just a shell
script that runs "isql".  I supposed you could make "isql" owned by root and
use a setuid root C program as a replacement for sperform, so users would
only be able to use "isql" when called through "sperform".  This would
make all of the users "root", though, and is probably even worse (considering
that sperform has a shell escape) than the original problem.

Since INformix SQL is a front end - back end product, it would be nice if
there was a way for the back end (the SQL engine) to know which front end
(the sperform, isql, or 4GL application) was running and control access to the
tables according to this data, as well as by user or group ids.
------------- 
James B. O'Connor			jim@tiamat.fsc.com
Filtration Sciences Corporation		615/821-4022 x. 651

*** Altos users unite! mail to "info-altos-request@tiamat.fsc.com" ***

tim@phobos.sybase.com (Tim Wood) (05/16/89)

In article <1347@infmx.UUCP> aland@infmx.UUCP (alan denney) writes:

>In article <1092@altos86.UUCP> jon@altos86.UUCP (Jonathan Ma) writes:

>>In article <1080@investor.UUCP> news@investor.UUCP ( Bob Peirce) writes:

>>>We have a database we want to keep most people from updating or
>>>inserting except under controlled circumstances; ie, No from sperform,
>>>but YES from a 4GL data entry program.  
>>>-- 
>>>Bob Peirce, Pittsburgh, PA				 412-471-5320

>>	You can do the following as root:
>>	% cd $INFORMIXDIR/bin
>>	% chmod 500 sperform
>>

>
>Sorry, Jon, but this not a good idea.  Even in 2.10.00 and earlier 
>versions, this would prevent ALL users from running ANY forms. [...]
>
>As I see it, a better route would be to be able to grant permissions
>to *applications*, like "Application Plans" in DB2.

Or "stored procedures" and views in Sybase.  Moreover, you can grant
EXECUTE permission on the procedure (or SELECT, etc. on the view) and
revoke SELECT, UPDATE, etc. on the objects the procedure or view
references.  This implements a package-type interface to the database,
in that you can force all SQL operations to be performed via the
(statically-defined, parameterized) procedures and views.
-TW



Sybase, Inc. / 6475 Christie Ave. / Emeryville, CA / 94608	  415-596-3500
tim@sybase.com          {pacbell,pyramid,sun,{uunet,ucbvax}!mtxinu}!sybase!tim
Voluntary disclaimer: This message is solely my personal opinion.
		      It is not a representation of Sybase, Inc.  OK.

news@investor.UUCP ( Bob Peirce) (05/20/89)

In article <1347@infmx.UUCP> aland@infmx.UUCP (alan denney) writes:
>In article <1092@altos86.UUCP> jon@altos86.UUCP (Jonathan Ma) writes:
>>In article <1080@investor.UUCP> news@investor.UUCP ( Bob Peirce) writes:
>>>We have a database we want to keep most people from updating or
>>>inserting except under controlled circumstances; ie, No from sperform,
>>>but YES from a 4GL data entry program.  
>>
>>	You can do the following as root:
>>	% cd $INFORMIXDIR/bin
>>	% chmod 500 sperform
>>
>
>The only way to get the desired functionality that I know of (in UNIX)
>is to create a "phony" generic user name for the application,
>grant it the appropriate database permissions, make it the program 
>owner, and use setuid().
>
Sorry doctor, but that was the first thing we tried.  In fact all our
database applications are owned by dbm.  4gl apparently considers
the real ID and not the effective ID and only root can change the real
ID.  Furthermore, 4gl apparently gets control very early making it
impossible to change the real ID even if you are root.

We have a solution which came from a gentleman at NCR near Boulder,  CO. 
Unfortunately I did not write down his name or site when he called so I
cannot give proper attribution.  However, the essence of the procedure is
to have a C routine file, part of which has your ID setting routines. 
Then have a shell script which runs after main.4gl finally gets to
main.c which goes into main.c and inserts a call to the setid function
before the first 4gl function call.  We put this in the makefile so the
whole thing works automatically.  Make the final program owned by root
and run suid.  The pertinent part of our makefile now looks like this.

#  makefile for invest 4gl program

FGLC = /usr/informix/lib/fglc
FGLC2 = /usr/informix/lib/fglc2 -4GL
CFLAGS = -I/usr/informix/incl
LD = /usr/informix/lib
LIB = ${LD}/lib4gl.a ${LD}/libforms.a ${LD}/libsql.a

...  Other stuff

invest.ec: invest.4gl
	$(FGLC) invest.4gl
invest.c: invest.ec
	$(FGLC2) invest.ec
invest.o: invest.c
	sh fix-invest.c
	cc $(CFLAGS) -c invest.c

...  Even more stuff


And fix-invest.c looks like this:

cp invest.c invest.b
sed < invest.b > invest.c -e '/fgl_init/i\
setids();

'
rm invest.b

Fgl_init is the first 4gl routine called, at least in this progarm and
probably in all 4gl programs.  Thus the C function, setids(), gets run
before fgl_init can run.  It changes the real and effective IDs to dbm
so fgl_init can't do anything about it.

There is one security hole.  We provide shell escapes.  Unfortunately,
once root has set the ID to dbm, dbm can't reset it to the real user.  I
suppose we could get around this by forking the program and running the
parent as root and the child as dbm.  Unfortunately, that is too hairy
for my meager C coding skills, so we just trap out the shell escapes so
only a limited list of users can use them.  This is hardwired in, not a
good idea, but easy and this won't require much change.

All in all a nice solution to a tricky problem.  Thanks, whoever you were!

-- 
Bob Peirce, Pittsburgh, PA				 412-471-5320
uucp: ...!{allegra, bellcore, cadre, idis, psuvax1}!pitt!investor!rbp
	    NOTE:  Mail must be < 30K  bytes/message

john@riddle.UUCP (Jonathan Leffler) (05/22/89)

In article <1347@infmx.UUCP> aland@infmx.UUCP (alan denney) writes:
>>>We have a database we want to keep most people from updating or
>>>inserting except under controlled circumstances; ie, No from sperform,
>>>but YES from a 4GL data entry program.  
>
>The only way to get the desired functionality that I know of (in UNIX)
>is to create a "phony" generic user name for the application,
>grant it the appropriate database permissions, make it the program 
>owner, and use setuid().
>

Unfortunately, setuid programs do not work with Informix, unless
they are setuid root!

Reasoning:
John is logged in as john/consult (uid=504, euid=504, gid=500, egid=500)
Program is owned dbappl/dbappl (uid=70, gid=70, perms=6511 -- setuid dbappl)
John runs Program: process has perms (uid=504, euid=70, gid=500, egid=70)
SQLEXEC is owned root/informix (uid=0, gid=50, perms=6511 -- setuid root)
Program runs SQLEXEC: process has perms (uid=504, euid=0, gid=500, egid=50)

Problem: SQLEXEC only knows about the real UID of John, not the
intermediate user dbappl. 

Comment { no flames on this bit, please }:
No criticism intended of anybody -- its just a fact of UNIX life that 
setuid programs cannot run other setuid programs and hand on the first 
setuid ownership.  It is an interesting question whether the permissions 
should be handed on automatically?  There are arguments for and against, 
and I suspect that it should be an option, a new file permission.  
However, as UNIX has survied for a while without it, I don't suppose 
anything will be done to fix this problem, even if it is admitted to be a 
problem by the powers that be.
End of comment {end of flame-proof section}.

Circumvention: Program has to be owned root, setuid root; it has
to look up the real UID of dbappl (getpwnam(3)) and do a
setuid(2).  Because EUID is 0, this will set *BOTH* euid and uid,
giving the revised reasoning:

John is logged in as john/consult (uid=504, euid=504, gid=500, egid=500)
Program is owned root/dbappl (uid=0, gid=70, perms=6511 -- setuid dbappl)
John runs Program: process has perms (uid=504, euid=0, gid=500, egid=70)
Program does setuid: process has perms (uid=70, euid=70, gid=500, egid=70)
SQLEXEC is owned root/informix (uid=0, gid=50, perms=6511 -- setuid root)
Program runs SQLEXEC: process has perms (uid=70, euid=0, gid=500, egid=50)

Note: Program has to do its setuid trick prior to opening the
database.

A simpler way of achieving a similar effect is to make people
login as dbappl -- login does the setuid for you and is known to
be (reasonably) reliable.  The profile can be made to run the
application, and only the application, so presumably people can
do no damage with it.  (There weren't any shell escapes, were
there?)

Jonathan Leffler (john@sphinx.co.uk)

leo@philmds.UUCP (Leo de Wit) (05/22/89)

In article <1084@investor.UUCP> rbp@investor.UUCP (Bob Peirce #305) writes:
    []
|Sorry doctor, but that was the first thing we tried.  In fact all our
|database applications are owned by dbm.  4gl apparently considers
|the real ID and not the effective ID and only root can change the real
|ID.  Furthermore, 4gl apparently gets control very early making it
|impossible to change the real ID even if you are root.

Nope. Any process can change its real UID to its effective UID, or its
effective to its real (and the same goes for group IDs).  If you need
the control very early, just create a program (setuid dbm) that sets
the real UID to the effective, then execs the required program.

gupta@cullsj.UUCP (Yogesh Gupta) (05/23/89)

In article <1347@infmx.UUCP>, aland@infmx.UUCP (Dr. Scump) writes:
< In article <1092@altos86.UUCP> jon@altos86.UUCP (Jonathan Ma) writes:
< >In article <1080@investor.UUCP> news@investor.UUCP ( Bob Peirce) writes:
< >>We have a database we want to keep most people from updating or
< >>inserting except under controlled circumstances; ie, No from sperform,
< >>but YES from a 4GL data entry program.  
< >>-- 
< >>Bob Peirce, Pittsburgh, PA				 412-471-5320
< >	You can do the following as root:
< >	% cd $INFORMIXDIR/bin
< >	% chmod 500 sperform
< >
< 
< As I see it, a better route would be to be able to grant permissions
< to *applications*, like "Application Plans" in DB2.
< 
<     Alan S. Denney  @  Informix Software, Inc.    

Yes, that is extremely useful.  And you can do exaclty that with Cullinet's
Enterprise:DB.  It allows the owner of a program to grant EXECUTE authority
on a program, even though the person executing it might not have any other
authority.  Also, since our application builder generates applications
that are no different from user written applications, you can authorize
them similarly.

dberg@cod.NOSC.MIL (David I. Berg) (05/23/89)

In article <1347@infmx.UUCP>, aland@infmx.UUCP (Dr. Scump) writes:
> In article <1092@altos86.UUCP> jon@altos86.UUCP (Jonathan Ma) writes:
> >In article <1080@investor.UUCP> news@investor.UUCP ( Bob Peirce) writes:
> >>We have a database we want to keep most people from updating or
> >>inserting except under controlled circumstances; ie, No from sperform,
> >>but YES from a 4GL data entry program.  
> >>-- 

As inelegant as it may seem to be, we solved the problem by adding a
permissions table to the database.  Each row represents a user; each
column represents a "functional" application.  The column values can
be from a domain as simple as Y or N to as complex as a set of values 
for different levels of permissions.  The 4GL program obtains UID upon
entry and reads the row in the permission table corresponding to that
UID into an array in the program.  Each functional application checks
its appropriate entry in the array to see if the user has permission
to execute it.

-- 
David I. Berg (dberg@nosc.mil)
GENISYS Information Systems, Inc., 4250 Pacific Hwy #118, San Diego, CA 92110
MILNET: dberg@nosc.mil
UUCP:   {akgua decvax dcdwest ucbvax}!sdcsvax!noscvax!dberg

jim@tiamat.fsc.com (Jim O'Connor) (06/04/89)

* > >In article <1080@investor.UUCP> news@investor.UUCP ( Bob Peirce) writes:
* > >>We have a database we want to keep most people from updating or
* > >>inserting except under controlled circumstances; ie, No from sperform,
* > >>but YES from a 4GL data entry program.  
* > >>-- 
* 
* As inelegant as it may seem to be, we solved the problem by adding a
* permissions table to the database.  Each row represents a user; each
* column represents a "functional" application.  The column values can
* be from a domain as simple as Y or N to as complex as a set of values 
* for different levels of permissions.  The 4GL program obtains UID upon
* entry and reads the row in the permission table corresponding to that
* UID into an array in the program.  Each functional application checks
* its appropriate entry in the array to see if the user has permission
* to execute it.

But how do you keep the user from running "isql" and then tinkering with
the data that they have access to with any arbitrary RDSQL statement.

In the 4GL application, you can make sure the user only performs "logical"
operations on the data they have access to, but if they have a way to
run "isql" they can do whatever they want.

------------- 
James B. O'Connor			jim@tiamat.fsc.com
Filtration Sciences Corporation		615/821-4022 x. 651

*** Altos users unite! mail to "info-altos-request@tiamat.fsc.com" ***

dberg@cod.NOSC.MIL (David I. Berg) (06/07/89)

In article <585@tiamat.fsc.com>, jim@tiamat.fsc.com (Jim O'Connor) writes:
> But how do you keep the user from running "isql" and then tinkering with
> the data that they have access to with any arbitrary RDSQL statement.

With controlled access to isql -- i.e., owner and group access only. 
(In my case, the users know not of the existence of isql or what to do
with it.  The DBAs access the databases remotely whenever isql work must
be done.)

-- 
David I. Berg (dberg@nosc.mil)
GENISYS Information Systems, Inc., 4250 Pacific Hwy #118, San Diego, CA 92110
MILNET: dberg@nosc.mil
UUCP:   {akgua decvax dcdwest ucbvax}!sdcsvax!noscvax!dberg