1262566Sdes/* $Id: bsd-setres_id.c,v 1.2 2013/12/07 21:23:09 djm Exp $ */
2248613Sdes
3248613Sdes/*
4248613Sdes * Copyright (c) 2012 Darren Tucker (dtucker at zip com au).
5248613Sdes *
6248613Sdes * Permission to use, copy, modify, and distribute this software for any
7248613Sdes * purpose with or without fee is hereby granted, provided that the above
8248613Sdes * copyright notice and this permission notice appear in all copies.
9248613Sdes *
10248613Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11248613Sdes * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12248613Sdes * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13248613Sdes * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14248613Sdes * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15248613Sdes * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16248613Sdes * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17248613Sdes */
18248613Sdes
19248613Sdes#include "includes.h"
20248613Sdes
21248613Sdes#include <sys/types.h>
22248613Sdes
23248613Sdes#include <stdarg.h>
24248613Sdes#include <unistd.h>
25262566Sdes#include <string.h>
26248613Sdes
27248613Sdes#include "log.h"
28248613Sdes
29248613Sdes#if !defined(HAVE_SETRESGID) || defined(BROKEN_SETRESGID)
30248613Sdesint
31248613Sdessetresgid(gid_t rgid, gid_t egid, gid_t sgid)
32248613Sdes{
33248613Sdes	int ret = 0, saved_errno;
34248613Sdes
35248613Sdes	if (rgid != sgid) {
36248613Sdes		errno = ENOSYS;
37248613Sdes		return -1;
38248613Sdes	}
39248613Sdes#if defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID)
40248613Sdes	if (setregid(rgid, egid) < 0) {
41248613Sdes		saved_errno = errno;
42248613Sdes		error("setregid %u: %.100s", rgid, strerror(errno));
43248613Sdes		errno = saved_errno;
44248613Sdes		ret = -1;
45248613Sdes	}
46248613Sdes#else
47248613Sdes	if (setegid(egid) < 0) {
48248613Sdes		saved_errno = errno;
49248613Sdes		error("setegid %u: %.100s", (u_int)egid, strerror(errno));
50248613Sdes		errno = saved_errno;
51248613Sdes		ret = -1;
52248613Sdes	}
53248613Sdes	if (setgid(rgid) < 0) {
54248613Sdes		saved_errno = errno;
55248613Sdes		error("setgid %u: %.100s", rgid, strerror(errno));
56248613Sdes		errno = saved_errno;
57248613Sdes		ret = -1;
58248613Sdes	}
59248613Sdes#endif
60248613Sdes	return ret;
61248613Sdes}
62248613Sdes#endif
63248613Sdes
64248613Sdes#if !defined(HAVE_SETRESUID) || defined(BROKEN_SETRESUID)
65248613Sdesint
66248613Sdessetresuid(uid_t ruid, uid_t euid, uid_t suid)
67248613Sdes{
68248613Sdes	int ret = 0, saved_errno;
69248613Sdes
70248613Sdes	if (ruid != suid) {
71248613Sdes		errno = ENOSYS;
72248613Sdes		return -1;
73248613Sdes	}
74248613Sdes#if defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID)
75248613Sdes	if (setreuid(ruid, euid) < 0) {
76248613Sdes		saved_errno = errno;
77248613Sdes		error("setreuid %u: %.100s", ruid, strerror(errno));
78248613Sdes		errno = saved_errno;
79248613Sdes		ret = -1;
80248613Sdes	}
81248613Sdes#else
82248613Sdes
83248613Sdes# ifndef SETEUID_BREAKS_SETUID
84248613Sdes	if (seteuid(euid) < 0) {
85248613Sdes		saved_errno = errno;
86248613Sdes		error("seteuid %u: %.100s", euid, strerror(errno));
87248613Sdes		errno = saved_errno;
88248613Sdes		ret = -1;
89248613Sdes	}
90248613Sdes# endif
91248613Sdes	if (setuid(ruid) < 0) {
92248613Sdes		saved_errno = errno;
93248613Sdes		error("setuid %u: %.100s", ruid, strerror(errno));
94248613Sdes		errno = saved_errno;
95248613Sdes		ret = -1;
96248613Sdes	}
97248613Sdes#endif
98248613Sdes	return ret;
99248613Sdes}
100248613Sdes#endif
101