Back to index

glibc  2.9
setresuid.c
Go to the documentation of this file.
00001 /* Copyright (C) 1998,2000,2002,2003,2004,2005,2006
00002        Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <errno.h>
00021 #include <unistd.h>
00022 #include <setxid.h>
00023 #include <linux/posix_types.h>
00024 #include <kernel-features.h>
00025 
00026 
00027 #if defined __NR_setresuid || defined __NR_setresuid32
00028 
00029 # ifdef __NR_setresuid32
00030 #  if __ASSUME_32BITUIDS == 0
00031 /* This variable is shared with all files that need to check for 32bit
00032    uids.  */
00033 extern int __libc_missing_32bit_uids;
00034 #  endif
00035 # endif /* __NR_setresuid32 */
00036 
00037 int
00038 __setresuid (uid_t ruid, uid_t euid, uid_t suid)
00039 {
00040   int result;
00041 
00042 # if __ASSUME_32BITUIDS > 0 || !defined __NR_setresuid
00043   result = INLINE_SETXID_SYSCALL (setresuid32, 3, ruid, euid, suid);
00044 # else
00045 #  ifdef __NR_setresuid32
00046   if (__libc_missing_32bit_uids <= 0)
00047     {
00048       int saved_errno = errno;
00049 
00050       result = INLINE_SETXID_SYSCALL (setresuid32, 3, ruid, euid, suid);
00051       if (result == 0)
00052        goto out;
00053       if (errno != ENOSYS)
00054        return result;
00055 
00056       __set_errno (saved_errno);
00057       __libc_missing_32bit_uids = 1;
00058     }
00059 #  endif /* __NR_setresuid32 */
00060 
00061   if (((ruid + 1) > (uid_t) ((__kernel_uid_t) -1U))
00062       || ((euid + 1) > (uid_t) ((__kernel_uid_t) -1U))
00063       || ((suid + 1) > (uid_t) ((__kernel_uid_t) -1U)))
00064     {
00065       __set_errno (EINVAL);
00066       return -1;
00067     }
00068 
00069   result = INLINE_SETXID_SYSCALL (setresuid, 3, ruid, euid, suid);
00070 #  ifdef __NR_setresuid32
00071  out:
00072 #  endif
00073 # endif
00074 
00075   return result;
00076 }
00077 libc_hidden_def (__setresuid)
00078 #ifndef __setresuid
00079 weak_alias (__setresuid, setresuid)
00080 #endif
00081 
00082 #else
00083 
00084 #include <posix/setresuid.c>
00085 
00086 #endif