Initial import
[samba] / source / lib / util_smbd.c
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 */
40 BOOL 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(NULL, primary_gid, &groups, &ngrp);
77
78         for (i=0; i<max_grp; i++)
79                 add_gid_to_array_unique(NULL, temp_groups[i], &groups, &ngrp);
80
81         *ngroups = ngrp;
82         *ret_groups = groups;
83         SAFE_FREE(temp_groups);
84         return True;
85 }
86