~ubuntu-branches/ubuntu/oneiric/sbuild/oneiric

« back to all changes in this revision

Viewing changes to wrapper/wrapper.cc

  • Committer: Bazaar Package Importer
  • Author(s): Lorenzo De Liso
  • Date: 2011-05-01 16:55:16 UTC
  • mfrom: (8.1.19 upstream) (3.3.17 sid)
  • Revision ID: james.westby@ubuntu.com-20110501165516-8g3uwrnhv2bzjt8y
Tags: 0.62.2-1ubuntu1
* Merge from debian unstable, remaining changes:
  - debian/patches/do-not-install-debfoster-into-chroots.patch: 
    do not install debfoster into the chroots because it is in universe and 
    not needed for package building itself.
  - debian/patches/run-pre-build-hooks-as-root.patch: 
    run pre-build hooks as root (Closes: #607228)
* Now that the package uses a patch system, don't modify the files directly;
  instead, put the changes in the respective patches and add the DEP-3
  patch tagging guidelines to them.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright © 2005-2011  Roger Leigh <rleigh@debian.org>
 
2
 *
 
3
 * sbuild is free software: you can redistribute it and/or modify it
 
4
 * under the terms of the GNU General Public License as published by
 
5
 * the Free Software Foundation, either version 2 of the License, or
 
6
 * (at your option) any later version.
 
7
 *
 
8
 * sbuild is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
11
 * General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program.  If not, see
 
15
 * <http://www.gnu.org/licenses/>.
 
16
 *
 
17
 *********************************************************************/
 
18
 
 
19
#include <iostream>
 
20
#include <cassert>
 
21
#include <cerrno>
 
22
#include <cstring>
 
23
#include <cstdlib>
 
24
 
 
25
#include "util.h"
 
26
 
 
27
using namespace sbuild;
 
28
/**
 
29
 * Check group membership.
 
30
 *
 
31
 * @param group the group to check for.
 
32
 * @returns true if the user is a member of group, otherwise false.
 
33
 */
 
34
bool
 
35
is_group_member (sbuild::group const& group)
 
36
{
 
37
  errno = 0;
 
38
 
 
39
  bool group_member = false;
 
40
  if (group.gr_gid == getgid())
 
41
    {
 
42
      group_member = true;
 
43
    }
 
44
  else
 
45
    {
 
46
      int supp_group_count = getgroups(0, 0);
 
47
      if (supp_group_count < 0)
 
48
        {
 
49
          std::cerr << "Failed to get supplementary group count" << std::endl;
 
50
          exit (1);
 
51
        }
 
52
      if (supp_group_count > 0)
 
53
        {
 
54
          gid_t *supp_groups = new gid_t[supp_group_count];
 
55
          assert (supp_groups);
 
56
          if (getgroups(supp_group_count, supp_groups) < 1)
 
57
            {
 
58
              // Free supp_groups before throwing to avoid leak.
 
59
              delete[] supp_groups;
 
60
              std::cerr << "Failed to get supplementary groups: "
 
61
                        << strerror(errno) << std::endl;
 
62
              exit(1);
 
63
            }
 
64
 
 
65
          for (int i = 0; i < supp_group_count; ++i)
 
66
            {
 
67
              if (group.gr_gid == supp_groups[i])
 
68
                group_member = true;
 
69
            }
 
70
          delete[] supp_groups;
 
71
        }
 
72
    }
 
73
 
 
74
  return group_member;
 
75
}
 
76
 
 
77
const char *sbuild_user = "sbuild";
 
78
const char *sbuild_group = "sbuild";
 
79
 
 
80
int
 
81
main (int argc, char *argv[])
 
82
{
 
83
  bool in_group = false;
 
84
 
 
85
  sbuild::group grp(sbuild_group);
 
86
  if (!grp)
 
87
    {
 
88
      if (errno == 0)
 
89
        {
 
90
          std::cerr << "Group '" << sbuild_group << "' not found" << std::endl;
 
91
        }
 
92
      else
 
93
        {
 
94
          std::cerr << "Group '" << sbuild_group << "' not found: "
 
95
                    << strerror(errno) << std::endl;
 
96
        }
 
97
      exit(1);
 
98
    }
 
99
 
 
100
  sbuild::passwd current_user(getuid());
 
101
  if (!current_user)
 
102
    {
 
103
      if (errno == 0)
 
104
        {
 
105
          std::cerr << "User '" << getuid() << "' not found" << std::endl;
 
106
        }
 
107
      else
 
108
        {
 
109
          std::cerr << "User '" << getuid() << "' not found: "
 
110
                    << strerror(errno) << std::endl;
 
111
        }
 
112
      exit(1);
 
113
    }
 
114
 
 
115
  sbuild::passwd new_user(sbuild_user);
 
116
  if (!new_user)
 
117
    {
 
118
      if (errno == 0)
 
119
        {
 
120
          std::cerr << "User '" << sbuild_user << "' not found" << std::endl;
 
121
        }
 
122
      else
 
123
        {
 
124
          std::cerr << "User '" << sbuild_user << "' not found: "
 
125
                    << strerror(errno) << std::endl;
 
126
        }
 
127
      exit(1);
 
128
    }
 
129
 
 
130
  sbuild::group new_group(new_user.pw_gid);
 
131
  if (!new_group)
 
132
    {
 
133
      if (errno == 0)
 
134
        {
 
135
          std::cerr << "Group '" << new_user.pw_gid << "' not found" << std::endl;
 
136
        }
 
137
      else
 
138
        {
 
139
          std::cerr << "Group '" << new_user.pw_gid << "' not found: "
 
140
                    << strerror(errno) << std::endl;
 
141
        }
 
142
      exit(1);
 
143
    }
 
144
 
 
145
  // Check primary group
 
146
  if (current_user.pw_gid == grp.gr_gid)
 
147
    in_group = true;
 
148
 
 
149
  // Check supplementary groups
 
150
  if (is_group_member(grp))
 
151
    in_group = true;
 
152
 
 
153
  // Root is allowed to skip the permissions checks, i.e. not be
 
154
  // required to be in the sbuild group.
 
155
  if (current_user.pw_uid != 0 && !in_group) {
 
156
      std::cerr << "Permission denied: not a member of group sbuild"  << std::endl;
 
157
      exit(1);
 
158
  }
 
159
 
 
160
  // Set primary group
 
161
  if (setgid (new_user.pw_gid))
 
162
    {
 
163
      std::cerr << "Failed to set group '" << new_group.gr_name << "': "
 
164
                << strerror(errno) << std::endl;
 
165
      exit(1);
 
166
    }
 
167
 
 
168
  // Set supplementary groups
 
169
  if (initgroups (new_user.pw_name, new_user.pw_gid))
 
170
    {
 
171
      std::cerr << "Failed to set supplementary groups: "
 
172
                << strerror(errno) << std::endl;
 
173
      exit(1);
 
174
    }
 
175
 
 
176
  // Set user
 
177
  if (setuid (new_user.pw_uid))
 
178
    {
 
179
      std::cerr << "Failed to set user '" << new_user.pw_name << "': "
 
180
                << strerror(errno) << std::endl;
 
181
      exit(1);
 
182
    }
 
183
 
 
184
  // Check we're not still root
 
185
  if (!setuid (0))
 
186
    {
 
187
      std::cerr << "Failed to drop root permissions" << std::endl;
 
188
      exit(1);
 
189
    }
 
190
 
 
191
  // exec schroot under new identity
 
192
  execvp("schroot", argv);
 
193
  std::cerr << "Failed to exec 'schroot'" << std::endl;
 
194
  exit(1);
 
195
}