FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Debian > Debian User

 
 
LinkBack Thread Tools
 
Old 01-08-2010, 10:40 PM
Frank Miles
 
Default Daemon impotent after dropping priviledges with setuid()

I have a peculiar problem with a daemon. Some of the tasks that the daemon
needs to accomplish should be done with reduced priviledges, particularly
if they are complex or depend on user input. So the daemon forks a child
process, which setuid's to some lesser user.

Unfortunately, as soon as the daemon setuid(some_other_userid), it can
no longer write files. Not into the home directory of some_other_userid,
not into /tmp, ... I haven't found anywhere that the daemon can write
without receiving a "permission denied" error.

The files didn't exist before the daemon action. Permissions to /tmp
are 777+t. Doing a getuid(), geteuid() show that the permissions were
set properly in the daemon's child process.

The same user can write files into these same directories without error
from the console or from a plain 'C' program. The daemon's child
(before setuid) also succeeds at writing files. 'strace -f' doesn't
show any problem until the open() call results in the permission denied
error.

This is on a 'squeeze' system, 64 bit i7 860 that otherwise seems to run
properly.

Anyone have any hints? Suggestions for diagnosing things? Would be
appreciated!!

-f


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
 
Old 01-12-2010, 03:27 PM
Frank Miles
 
Default Daemon impotent after dropping priviledges with setuid()

I think I understand what's happening, though I'm not sure that it should...

After the daemon's double-fork (with setsid()), the utility of the group
identification seems lost.

With a bit more detail:
Say I have a directory owned by user "user1", who is a member of
"group1"; and that "user2" is also a member of "group1". The directory
is set up to have group write permissions.
Before the double-fork, yada yada, all members of "group1" can
write to this directory. After the double-fork, only "user1" can write
to the directory.

It doesn't seem right, but that is what I observe.

The even stranger thing is that the program will append to an existing file...
just not create a new file. This seems wrong.

Am I ignorant? Does this happen on other people's machines? Here's a simple
program that should demonstrate the problem, if you substitute three names,
see below:

======================================= testuid.c

/* testuid.c Testing post-setuid() functionality.
*/

#include <sys/types.h> // pid_t
#include <unistd.h> // getuid()
#include <stdio.h>
#include <string.h>

// ------------------ MAKE APPROPRIATE SUBSTITUTIONS FOR THESE:

#define DIR_FILE_NAME "/full/path/filename"
#define ALT_GRP_ID 1000 // substitute group id
#define ALT_USER_ID 1000 // substitute user id

// ------------------ WRITE FILE TO PATH/NAME

#define MAX_FILE_LEN 512
#define MAX_EXTN_LEN 10
#define MAX_PARTIAL_FLEN (MAX_FILE_LEN-(MAX_EXTN_LEN+2))

static int writeDiagFile(const char *extn, const char *msg)
{
char fname[MAX_FILE_LEN];
FILE *f= NULL;

strncpy(fname, DIR_FILE_NAME, MAX_PARTIAL_FLEN);
fname[MAX_PARTIAL_FLEN - 1]= '';
strcat(fname, ".");
strncat(fname, extn, MAX_EXTN_LEN);
fname[MAX_FILE_LEN-1]= '';

f= fopen(fname, "a+");
if (!f)
{ fprintf(stderr, "Unable to open file [%s] for writing by (%d,%d)", fname, getuid(),geteuid());
perror("fopen");
return -1;
}
fprintf(f, "Msg {%s} <= %s as %d
", extn, msg, getuid());
fclose(f);
return 0;
}

int main(int argc, char * const argv[])
{
int retval;
pid_t xpid, ypid;

if (writeDiagFile("beginning user", "1"))
return -10;
xpid= fork();
if (0 > xpid)
{ perror("fork problem");
return xpid;
}
if (0 == xpid) // only child does more
{ if (writeDiagFile("child - after 1st fork", "2"))
return -11;

setsid();
if (writeDiagFile("child - after fork/setsid()", "3"))
return -12;

ypid= fork();
if (0 > ypid)
{ perror("fork problem");
return ypid;
}
if (0 == ypid) // only child does more
{ if (writeDiagFile("child - after fork/setsid/fork", "4"))
return -13;
retval= setgid(ALT_GRP_ID); // valid group on system
if (retval)
{ perror("setgid");
return retval;
}
retval= setuid(ALT_USER_ID); // valid user on system
if (retval)
{ perror("setuid");
return retval;
}

if (writeDiagFile("child - after fork/setsid/fork/setuid", "5"))
return -14;
putc('
', stderr);
}
}
return retval;
}

======================================= testuid.c
gcc -Wall testuid.c -o testuid

Run as root to be able to change user & group.
Feel free to tell me about the stupid and obvious mistake[s].
I'm assuming that my use of stderr isn't the problem - the
earliest incarnation (in a daemon) didn't have the fprintf's,
but it had the same problem writing to a directory.


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
 

Thread Tools




All times are GMT. The time now is 01:02 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org