X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fuid.c;h=817ac6590802568e718675b67d954a052838a160;hb=4054f4b3c85ecab060dafd46c0d3632cadbb5803;hp=4db2ce3317661488fdb3443a3dd1c9c86a89159e;hpb=a7349ad51dd4d6e119ab7414fd19d6a8467f3f35;p=netatalk.git diff --git a/etc/afpd/uid.c b/etc/afpd/uid.c index 4db2ce33..817ac659 100644 --- a/etc/afpd/uid.c +++ b/etc/afpd/uid.c @@ -1,5 +1,5 @@ /* - * $Id: uid.c,v 1.6 2001-12-03 05:03:38 jmarcus Exp $ + * $Id: uid.c,v 1.14 2005-04-28 20:49:45 bfernhomberg Exp $ * code: jeff@univrel.pr.uconn.edu * * These functions are abstracted here, so that all calls for resolving @@ -16,7 +16,8 @@ #include #include -#include +#include +#include /* functions for username and group */ #include @@ -27,27 +28,42 @@ #include #endif /* HAVE_UNISTD_H */ +extern uid_t uuid; + void save_uidgid ( pair ) -uidgidset **pair; +uidgidset *pair; { - /* allocate the memory */ - pair = malloc ( sizeof ( uidgidset ) ); - - /* then assign the values */ - (*pair)->uid = geteuid (); - (*pair)->gid = getegid (); -} /* end function void save_uidgid ( pair ) */ + pair->uid = geteuid (); + pair->gid = getegid (); +} void restore_uidgid ( pair ) -uidgidset **pair; +uidgidset *pair; { - if ( seteuid ( (*pair)->uid ) < 0 ) - syslog ( LOG_ERR, "restore_uidgid: unable to seteuid '%s': %m", - (*pair)->uid ); - if ( setegid ( (*pair)->gid ) < 0 ) - syslog ( LOG_ERR, "restore_uidgid: unable to setegid '%s': %m", - (*pair)->gid ); -} /* end function void restore_uidgid ( pair ) */ + uid_t uid + gid_t gid; + + uid = geteuid (); + gid = getegid (); + + if (uid == pair->uid && gid == pair->gid) + return; + + if (seteuid(0) < 0) { + LOG(log_error, logtype_afpd, "set_uidgid: Could not switch back to root: %s", + strerror(errno)); + } + + if ( setegid ( pair->gid ) < 0 ) + LOG(log_error, logtype_afpd, "restore_uidgid: unable to setegid '%s': %s", + pair->gid, strerror(errno) ); + + if ( seteuid ( pair->uid ) < 0 ) + LOG(log_error, logtype_afpd, "restore_uidgid: unable to seteuid '%s': %s", + pair->uid, strerror(errno) ); + else + uuid = pair->uid; /* ugly hack for utommode */ +} void set_uidgid ( this_volume ) const struct vol *this_volume; @@ -55,19 +71,34 @@ const struct vol *this_volume; int uid, gid; /* derived ones go in here */ /* check to see if we have to switch users */ - if ( uid = user_to_uid ( (this_volume)->v_forceuid ) ) { - if ( seteuid ( uid ) < 0 ) - syslog ( LOG_ERR, "set_uidgid: unable to seteuid '%s': %m", - (this_volume)->v_forceuid ); - } /* end of checking for (this_volume)->v_forceuid */ + uid = user_to_uid ( (this_volume)->v_forceuid); + gid = group_to_gid ( (this_volume)->v_forcegid); + + if ((!uid || uid == geteuid()) && (!gid || gid == getegid())) + return; + + if ( seteuid(0) < 0) { + LOG(log_error, logtype_afpd, "set_uidgid: Could not switch back to root: %s", + strerror(errno)); + return; + } /* check to see if we have to switch groups */ - if ( gid = group_to_gid ( (this_volume)->v_forcegid ) ) { - if ( seteuid ( gid ) < 0 ) - syslog ( LOG_ERR, "set_uidgid: unable to setegid '%s': %m", - (this_volume)->v_forcegid ); + if ( gid ) { + if ( setegid ( gid ) < 0 ) + LOG(log_error, logtype_afpd, "set_uidgid: unable to setegid '%s': %s", + (this_volume)->v_forcegid, strerror(errno) ); } /* end of checking for (this_volume)->v_forcegid */ + if ( uid) { + if ( seteuid ( uid ) < 0 ) + LOG(log_error, logtype_afpd, "set_uidgid: unable to seteuid '%s': %s", + (this_volume)->v_forceuid, strerror(errno) ); + else + uuid = uid; /* ugly hack for utommode */ + + } /* end of checking for (this_volume)->v_forceuid */ + } /* end function void set_uidgid ( username, group ) */ int user_to_uid ( username ) @@ -75,11 +106,8 @@ char *username; { struct passwd *this_passwd; - /* free memory for pointer */ - this_passwd = malloc ( sizeof ( struct passwd ) ); - /* check for anything */ - if ( strlen ( username ) < 1 ) return 0; + if ( !username || strlen ( username ) < 1 ) return 0; /* grab the /etc/passwd record relating to username */ this_passwd = getpwnam ( username ); @@ -97,11 +125,8 @@ char *group; { struct group *this_group; - /* free memory for pointer */ - this_group = malloc ( sizeof ( struct group ) ); - /* check for anything */ - if ( strlen ( group ) < 1 ) return 0; + if ( !group || strlen ( group ) < 1 ) return 0; /* grab the /etc/groups record relating to group */ this_group = getgrnam ( group );