was: PtInit() doesn’t work from SUID root program.
In a nutshell, I have the need to do an automatic screen grab from an
SUID program that’s run by a normal user. If the program is run with
normal permissions (i.e. chmod 0755), the screen grab works fine.
However, if the program is run SUID (i.e. chmod 4755), the program does
not create any files. Here’s the example code that shows the issue:
//BEGIN EXAMPLE CODE//
//to compile: qcc octopus.c -o octopus -lph -lphexlib
#include <iostream.h>
#include <stdio.h>
#include <Pt.h>
// make sure we include BMP support!
#define PX_IMAGE_MODULES
#define PX_PHIMAGE_SUPPORT
#define PX_BMP_SUPPORT
#include <photon/PxImage.h>
int print(PhImage_t *image)
{
int iErrCode = 0;
PhDrawContext_t pdc = 0;
PpPrintContext_t mpPC;
PhPoint_t p = { 0, 0 };
mpPC = PpCreatePC();
if (mpPC)
{
// set up my context
if(!iErrCode)
{
PpSetPC(mpPC, Pp_PC_DRIVER, “/usr/bin/phs-to-ps”, 0);
PpSetPC(mpPC, Pp_PC_FILENAME, “grabscreen.phs”, 0);
Ph_rect xPrintArea;
xPrintArea.ul.x = 750;
xPrintArea.ul.y = 500;
xPrintArea.lr.x = 500;
xPrintArea.lr.y = 400;
PpSetPC(mpPC, Pp_PC_MARGINS, &xPrintArea, 0);
PhDim_t xPaperSize;
xPaperSize.w = 8500;
xPaperSize.h = 11000;
PpSetPC(mpPC, Pp_PC_PAPER_SIZE, &xPaperSize, 0);
PhDim_t xSourceSize;
xSourceSize.w = 1024;
xSourceSize.h = 768;
PpSetPC(mpPC, Pp_PC_SOURCE_SIZE, &xSourceSize, 0);
}
// initialize the print job
if(!iErrCode)
{
if(PpStartJob(mpPC))
iErrCode = 2;
}
// make the print context active
if(!iErrCode)
{
pdc = PpContinueJob(mpPC);
if(!pdc)
iErrCode = 3;
}
if (image == NULL)
{
cout << “ERROR: NULL image” << endl;
exit(1);
}
cout << "image size: " << image->size.w << “x” << image->size.h << endl;
PgSetPalette( image->palette, 0, 0, image->colors,
Pg_PALSET_SOFT, 0 );
iErrCode = PgDrawImage( image->image, image->type, &p,
&image->size, image->bpl, 0 );
cout << "iErrCode = " << iErrCode << endl;
PpEndJob(mpPC);
PpReleasePC(mpPC);
}
}
int snap(char *fname,PhRect_t rect)
{
int len;
char *mem;
PhImage_t *image;
// get the size of the shared memory you need for the image
if ((len=PgReadScreenSize(&rect))<=0) return -1;
// allocate shared memory to contain the image
if (!(mem=(char*)PgShmemCreate(len,NULL))) return -1;
// read the portion of the screen you’re interested in
if (image=PgReadScreen(&rect,mem))
{
// save the image to the file name given
PxWriteImage(fname,image,NULL,PX_IMAGE_BMP,0);
if ((image = PxLoadImage( fname, NULL )) == NULL) {
perror( “Unable to load image” );
return -1;
}
print(image);
}
// destroy the shared memory you used
PgShmemDestroy(mem);
return 0;
}
int main(int argc,char *argv[])
{
int i;
if (argc!=2)
{
printf("Usage: grab ");
exit(-1);
}
int iPtInit = PtInit("/dev/photon");
cout << "PtInit returned: " << iPtInit << endl;
// get a connection to Photon
if (iPtInit!=0)
{
perror(“Error: Could not connect to Photon.”);
exit(-1);
}
PhRect_t rect;
char fname[120];
//windows_rect(r,&rect);
rect.ul.x = 0;
rect.ul.y = 0;
rect.lr.x = 1023;
rect.lr.y = 767;
sprintf(fname,argv[1],i);
printf(“saving ‘%s’\n”,fname);
snap(fname,rect);
return 0;
}