added rid and sid_name_use to DOMAIN_GRP_MEMBER, for use in group member
[samba.git] / source3 / groupdb / groupunix.c
1 /*
2  * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
3  * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
4  * 
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License as published by the Free
7  * Software Foundation; either version 2 of the License, or (at your option)
8  * any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  * 
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 675
17  * Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #include "includes.h"
21
22 #ifdef USE_SMBUNIX_DB
23
24 extern int DEBUGLEVEL;
25
26
27 extern DOM_SID global_sam_sid;
28
29 /***************************************************************
30  Start to enumerate the grppasswd list. Returns a void pointer
31  to ensure no modification outside this module.
32 ****************************************************************/
33
34 static void *startgrpunixpwent(BOOL update)
35 {
36         setgrent();
37         return (void*)(-1);
38 }
39
40 /***************************************************************
41  End enumeration of the grppasswd list.
42 ****************************************************************/
43
44 static void endgrpunixpwent(void *vp)
45 {
46         endgrent();
47 }
48
49 /*************************************************************************
50  Return the current position in the grppasswd list as an SMB_BIG_UINT.
51  This must be treated as an opaque token.
52 *************************************************************************/
53 static SMB_BIG_UINT getgrpunixpwpos(void *vp)
54 {
55         return (SMB_BIG_UINT)0;
56 }
57
58 /*************************************************************************
59  Set the current position in the grppasswd list from an SMB_BIG_UINT.
60  This must be treated as an opaque token.
61 *************************************************************************/
62 static BOOL setgrpunixpwpos(void *vp, SMB_BIG_UINT tok)
63 {
64         return False;
65 }
66
67 /*************************************************************************
68  Routine to return the next entry in the smbdomaingroup list.
69  *************************************************************************/
70 BOOL get_unixgroup_members(struct group *grp,
71                                 int *num_mem, DOMAIN_GRP_MEMBER **members)
72 {
73         int i;
74         char *unix_name;
75
76         if (num_mem == NULL || members == NULL)
77         {
78                 return False;
79         }
80
81         (*num_mem) = 0;
82         (*members) = NULL;
83
84         for (i = 0; (unix_name = grp->gr_mem[i]) != NULL; i++)
85         {
86                 DOM_NAME_MAP gmep;
87                 DOMAIN_GRP_MEMBER *mem;
88                 uint32 rid;
89
90                 if (!lookupsmbpwnam (unix_name, &gmep) &&
91                     !lookupsmbgrpnam(unix_name, &gmep))
92                 {
93                         continue;
94                 }
95
96                 if (gmep.type != SID_NAME_DOM_GRP &&
97                     gmep.type != SID_NAME_USER &&
98                     gmep.type != SID_NAME_WKN_GRP)
99                 {
100                         DEBUG(0,("group database: name %s is not in a Domain Group\n",
101                                   unix_name));
102                         continue;
103                 }
104                         
105                 sid_split_rid(&gmep.sid, &rid);
106                 if (!sid_equal(&global_sam_sid, &gmep.sid))
107                 {
108                         DEBUG(0,("group database: could not resolve name %s (wrong Domain SID)\n",
109                                   unix_name));
110                         continue;
111                 }
112
113                 (*members) = Realloc((*members), ((*num_mem)+1) * sizeof(DOMAIN_GRP_MEMBER));
114                 if ((*members) == NULL)
115                 {
116                         return False;
117                 }
118
119                 mem = &(*members)[(*num_mem)];
120                 (*num_mem)++;
121
122                 fstrcpy(mem->name, gmep.nt_name);
123                 mem->attr    = 0x07;
124                 mem->sid_use = gmep.type;
125                 mem->rid     = rid;
126         }
127         return True;
128 }
129
130 /*************************************************************************
131  Routine to return the next entry in the domain group list.
132
133  if we are not a PDC or BDC, then we do NOT support Domain groups, only
134  aliases.  try running MUSRMGR.EXE or running USRMGR.EXE selected on a
135  workstation, you will find that no Domain groups are listed: only aliases.
136
137  so, as a PDC or BDC, all unix groups not explicitly mapped using
138  map_group_gid() are treated as Domain groups.
139
140  *************************************************************************/
141 static DOMAIN_GRP *getgrpunixpwent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem)
142 {
143         /* Static buffers we will return. */
144         static DOMAIN_GRP gp_buf;
145         struct group *unix_grp;
146
147         if (lp_server_role() == ROLE_DOMAIN_NONE || 
148             lp_server_role() == ROLE_DOMAIN_MEMBER)
149         {
150                 /*
151                  * only PDC and BDC have domain groups in the SAM.
152                  * (however as member of domain you can have LOCAL groups,
153                  * but that's dealt with in the aliasdb...)
154                  */
155
156                 return NULL;
157         }
158
159         gpdb_init_grp(&gp_buf);
160
161         fstrcpy(gp_buf.comment, "");
162         gp_buf.attr    = 0x07;
163
164         /* cycle through unix groups */
165         while ((unix_grp = getgrent()) != NULL)
166         {
167                 DOM_NAME_MAP gmep;
168                 DEBUG(10,("getgrpunixpwent: enum unix group entry %s\n",
169                            unix_grp->gr_name));
170                         
171                 if (!lookupsmbgrpgid(unix_grp->gr_gid, &gmep))
172                 {
173                         continue;
174                 }
175
176                 if (gmep.type != SID_NAME_DOM_GRP &&
177                     gmep.type != SID_NAME_WKN_GRP)
178                 {
179                         continue;
180                 }
181
182                 sid_split_rid(&gmep.sid, &gp_buf.rid);
183                 if (!sid_equal(&gmep.sid, &global_sam_sid))
184                 {
185                         continue;
186                 }
187
188                 fstrcpy(gp_buf.name, gmep.nt_name);
189                 break;
190         }
191
192         if (unix_grp == NULL)
193         {
194                 return NULL;
195         }
196
197         /* get the user's domain groups.  there are a maximum of 32 */
198
199         if (mem != NULL && num_mem != NULL)
200         {
201                 (*mem) = NULL;
202                 (*num_mem) = 0;
203
204                 get_unixgroup_members(unix_grp, num_mem, mem);
205         }
206
207         {
208                 pstring linebuf;
209                 make_group_line(linebuf, sizeof(linebuf), &gp_buf, mem, num_mem);
210                 DEBUG(10,("line: '%s'\n", linebuf));
211         }
212
213         return &gp_buf;
214 }
215
216 /************************************************************************
217  Routine to add an entry to the grppasswd file.
218 *************************************************************************/
219
220 static BOOL add_grpunixgrp_entry(DOMAIN_GRP *newgrp)
221 {
222         DEBUG(0, ("add_grpunixgrp_entry: NOT IMPLEMENTED\n"));
223         return False;
224 }
225
226 /************************************************************************
227  Routine to search the grppasswd file for an entry matching the groupname.
228  and then modify its group entry. We can't use the startgrppwent()/
229  getgrppwent()/endgrppwent() interfaces here as we depend on looking
230  in the actual file to decide how much room we have to write data.
231  override = False, normal
232  override = True, override XXXXXXXX'd out group or NO PASS
233 ************************************************************************/
234
235 static BOOL mod_grpunixgrp_entry(DOMAIN_GRP* grp)
236 {
237         DEBUG(0, ("mod_grpunixgrp_entry: NOT IMPLEMENTED\n"));
238         return False;
239 }
240
241
242 static struct groupdb_ops unix_ops =
243 {
244         startgrpunixpwent,
245         endgrpunixpwent,
246         getgrpunixpwpos,
247         setgrpunixpwpos,
248
249         iterate_getgroupntnam,          /* In groupdb.c */
250         iterate_getgroupgid,          /* In groupdb.c */
251         iterate_getgrouprid,          /* In groupdb.c */
252         getgrpunixpwent,
253
254         add_grpunixgrp_entry,
255         mod_grpunixgrp_entry,
256
257         iterate_getusergroupsnam      /* in groupdb.c */
258 };
259
260 struct groupdb_ops *unix_initialise_group_db(void)
261 {    
262         return &unix_ops;
263 }
264
265 #else
266  /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
267  void unix_grppass_dummy_function(void) { } /* stop some compilers complaining */
268 #endif /* USE_SMBPASS_DB */