source: branches/samba-3.2.x/source/lib/system_smbd.c@ 198

Last change on this file since 198 was 133, checked in by Paul Smedley, 18 years ago

Update trunk to 3.2.0pre3

File size: 4.6 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 system call wrapper interface.
4 Copyright (C) Andrew Tridgell 2002
5 Copyright (C) Andrew Barteltt 2002
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21/*
22 This file may assume linkage with smbd - for things like become_root()
23 etc.
24*/
25
26#include "includes.h"
27
28#ifndef HAVE_GETGROUPLIST
29
30/*
31 This is a *much* faster way of getting the list of groups for a user
32 without changing the current supplementary group list. The old
33 method used getgrent() which could take 20 minutes on a really big
34 network with hundeds of thousands of groups and users. The new method
35 takes a couple of seconds.
36
37 NOTE!! this function only works if it is called as root!
38 */
39
40static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups,
41 int *grpcnt)
42{
43 gid_t *gids_saved;
44 int ret, ngrp_saved, num_gids;
45
46 if (non_root_mode()) {
47 *grpcnt = 0;
48 return 0;
49 }
50
51 /* work out how many groups we need to save */
52 ngrp_saved = getgroups(0, NULL);
53 if (ngrp_saved == -1) {
54 /* this shouldn't happen */
55 return -1;
56 }
57
58 gids_saved = SMB_MALLOC_ARRAY(gid_t, ngrp_saved+1);
59 if (!gids_saved) {
60 errno = ENOMEM;
61 return -1;
62 }
63
64 ngrp_saved = getgroups(ngrp_saved, gids_saved);
65 if (ngrp_saved == -1) {
66 SAFE_FREE(gids_saved);
67 /* very strange! */
68 return -1;
69 }
70
71 if (initgroups(user, gid) != 0) {
72 DEBUG(0, ("getgrouplist_internals: initgroups() failed!\n"));
73 SAFE_FREE(gids_saved);
74 return -1;
75 }
76
77 /* this must be done to cope with systems that put the current egid in the
78 return from getgroups() */
79 save_re_gid();
80 set_effective_gid(gid);
81 setgid(gid);