1/*
2   Unix SMB/CIFS implementation.
3   Samba utility functions, used in smbd only
4   Copyright (C) Andrew Tridgell 2002
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include "includes.h"
22
23/*
24   This function requires sys_getgrouplist - which is only
25   available in smbd due to it's use of become_root() in a
26   legacy systems hack.
27*/
28
29/*
30  return a full list of groups for a user
31
32  returns the number of groups the user is a member of. The return will include the
33  users primary group.
34
35  remember to free the resulting gid_t array
36
37  NOTE! uses become_root() to gain correct priviages on systems
38  that lack a native getgroups() call (uses initgroups and getgroups)
39*/
40BOOL getgroups_user(const char *user, gid_t primary_gid, gid_t **ret_groups, int *ngroups)
41{
42	int ngrp, max_grp;
43	gid_t *temp_groups;
44	gid_t *groups;
45	int i;
46
47	max_grp = groups_max();
48	temp_groups = SMB_MALLOC_ARRAY(gid_t, max_grp);
49	if (! temp_groups) {
50		return False;
51	}
52
53	if (sys_getgrouplist(user, primary_gid, temp_groups, &max_grp) == -1) {
54
55		gid_t *groups_tmp;
56
57		groups_tmp = SMB_REALLOC_ARRAY(temp_groups, gid_t, max_grp);
58
59		if (!groups_tmp) {
60			SAFE_FREE(temp_groups);
61			return False;
62		}
63		temp_groups = groups_tmp;
64
65		if (sys_getgrouplist(user, primary_gid, temp_groups, &max_grp) == -1) {
66			DEBUG(0, ("get_user_groups: failed to get the unix group list\n"));
67			SAFE_FREE(temp_groups);
68			return False;
69		}
70	}
71
72	ngrp = 0;
73	groups = NULL;
74
75	/* Add in primary group first */
76	add_gid_to_array_unique(primary_gid, &groups, &ngrp);
77
78	for (i=0; i<max_grp; i++)
79		add_gid_to_array_unique(temp_groups[i], &groups, &ngrp);
80
81	*ngroups = ngrp;
82	*ret_groups = groups;
83	SAFE_FREE(temp_groups);
84	return True;
85}
86
87