Re: A quick question
Posted in 1991
Forwarded from rbp@investor.pgh.pa.us: From investor!rbp@vax.cs.pitt.edu Thu May 2 08:48:12 1991 Received: from vax.cs.pitt.edu by rmy.rmy.emory.edu (5.59/2.14.EUCC-MathCS) via SMTP id AA23294 ; Thu, 2 May 91 08:48:05 EST Received: from investor.UUCP by vax.cs.pitt.edu (5.65/1.14) id AA19429; Thu, 2 May 91 08:25:34 -0400 Received: by investor.pgh.pa.us (smail2.5) id AA20086; 2 May 91 07:28:02 EDT (Thu) To: rmy.emory.edu!informix-list-owner@vax.cs.pitt.edu Subject: Re: A quick question Message-Id: <9105020728.AA20086@investor.pgh.pa.us> Date: 2 May 91 07:28:02 EDT (Thu) From: rbp@investor.pgh.pa.us Can anybody think of a way to enable many users of a 4gl application select access to a database and its tables BUT disallowing those same users any kind of access to the same database and tables from sql? The motivation for this is that the users' actions can be controlled under the 4gl application but cannot be when using raw sql. You can run the program suid databaseowner. However, 4gl doesn't make this easy. Our version sets the uid back to the real user! The problem we ran into is that you canot insert the desired C function call in the 4gl program at an early enough point. Therefore you have to resort to the following nonsense in your makefile. Our 4gl program is called invest. 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 Fix-invest.c looks like this. It just inserts the setid call immediately after the fgl_init call made by the 4gl program. cp invest.c invest.b sed < invest.b > invest.c -e '/fgl_init/i\\ setids(); ' rm invest.b And setids() is int uid, dbm=6; /* Make it look like dbm is running this thing */ void setids() { uid=getuid(); if(setuid(dbm)) { perror("invest/setids"); exit(-1); } } Under SysVR2.2, only root or the uid itself can do the setuid! This means the program has to run suid root or suid dbm. Dbm is more secure. In either case, once you are running as dbm, it is impossible, as far as we can tell, to switch back to the real user before doing a shell escape. We are open to a way around this. In the meantime, we hardwire in the ids of the users we will permit to do shell escapes. The shell escape code looks like this. /* See if uid is one of 6-dbm, 100-rbp, 107-dmh or 117-bwm then call mysys */ void cksys(n) int n; { void mysys(); if(uid==6 || uid==100 || uid==107 || uid==117) mysys(n); else { fprintf(stderr,"\\n\\n\\ncksys(): You are not authorized for this command.\\n"); sleep(3); system("tput clear"); } return; } And mysys looks like this. /* Shell Escape */ /* Should set ids back to real user. Unfortunately, once we are running as dbm, we can't. Catch 22! */ void mysys(n) int n; { char str[STR]; int i; if ( n != 1 ) { fprintf(stderr,"\\n\\n\\nsystem(): Needs one arg. Got %d.\\n", n); sleep(3); return; } popquote ( str, STR ); for ( i=STR-1; i>0; --i ) if ( str[i] == ' ' ) str[i] = '\\0'; else break; system("tput clear"); system( str ); sleep(3); system("tput clear"); } /* mysystem */ I have not tried to improve any of this since we got it running. There may be better ways, but none of this code gets called very often so getting it running was more important than doing it the best way. ----- Bob Peirce, Pittsburgh, PA rbp@investor.pgh.pa.us 412-471-5320 venetia@investor.pgh.pa.us [NeXT Mail] ...!uunet!pitt!investor!rbp [UUCP]