last unix group not being listed. spotted by jacques sansdrap.
[samba.git] / source3 / groupdb / aliasunix.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 extern fstring global_sam_name;
29
30 struct unix_entries
31 {
32         struct group *grps;
33         int num_grps;
34         int grp_idx;
35 };
36
37 /***************************************************************
38  Start to enumerate the alspasswd list. Returns a void pointer
39  to ensure no modification outside this module.
40 ****************************************************************/
41
42 static void *startalsunixpwent(BOOL update)
43 {
44         struct unix_entries *grps;
45         grps = (struct unix_entries*)malloc(sizeof(struct unix_entries));
46
47         if (grps == NULL)
48         {
49                 return NULL;
50         }
51
52         if (!get_unix_grps(&grps->num_grps, &grps->grps))
53         {
54                 free(grps);
55                 return NULL;
56         }
57
58         grps->grp_idx = 0;
59
60         return (void*)grps;
61 }
62
63 /***************************************************************
64  End enumeration of the alspasswd list.
65 ****************************************************************/
66
67 static void endalsunixpwent(void *vp)
68 {
69         struct unix_entries *grps = (struct unix_entries *)vp;
70
71         if (grps != NULL)
72         {
73                 free_unix_grps(grps->num_grps, grps->grps);
74                 free(vp);
75         }
76 }
77
78 /*************************************************************************
79  Return the current position in the alspasswd list as an SMB_BIG_UINT.
80  This must be treated as an opaque token.
81 *************************************************************************/
82 static SMB_BIG_UINT getalsunixpwpos(void *vp)
83 {
84         return (SMB_BIG_UINT)0;
85 }
86
87 /*************************************************************************
88  Set the current position in the alspasswd list from an SMB_BIG_UINT.
89  This must be treated as an opaque token.
90 *************************************************************************/
91 static BOOL setalsunixpwpos(void *vp, SMB_BIG_UINT tok)
92 {
93         return False;
94 }
95
96 /*************************************************************************
97  Routine to return the next entry in the smbdomainalias list.
98  *************************************************************************/
99 BOOL get_unixalias_members(struct group *grp,
100                                 int *num_mem, LOCAL_GRP_MEMBER **members)
101 {
102         int i;
103         char *unix_name;
104
105         if (num_mem == NULL || members == NULL)
106         {
107                 return False;
108         }
109
110         (*num_mem) = 0;
111         (*members) = NULL;
112
113         for (i = 0; (unix_name = grp->gr_mem[i]) != NULL; i++)
114         {
115                 fstring name;
116                 DOM_NAME_MAP gmep;
117                 LOCAL_GRP_MEMBER *mem;
118
119                 fstrcpy(name, unix_name);
120
121                 if (!lookupsmbpwnam (name, &gmep) &&
122                     !lookupsmbgrpnam(name, &gmep))
123                 {
124                         continue;
125                 }
126
127                 if (!sid_front_equal(&global_sam_sid, &gmep.sid))
128                 {
129                         DEBUG(0,("alias database: could not resolve name %s (wrong Domain SID)\n",
130                                   name));
131                         continue;
132                 }
133
134                 (*num_mem)++;
135                 (*members) = Realloc((*members), (*num_mem) * sizeof(LOCAL_GRP_MEMBER));
136                 if ((*members) == NULL)
137                 {
138                         DEBUG(0,("get_unixalias_members: could not realloc LOCAL_GRP_MEMBERs\n"));
139                         return False;
140                 }
141
142                 mem = &(*members)[(*num_mem)-1];
143                 slprintf(mem->name, sizeof(mem->name)-1, "%s\\%s",
144                          gmep.nt_domain, gmep.nt_name);
145                 sid_copy(&mem->sid, &gmep.sid);
146                 mem->sid_use = gmep.type;
147
148                 DEBUG(10,("get_unixalias_members: adding alias %s\n",
149                            mem->name));
150         }
151         return True;
152 }
153
154 /*************************************************************************
155  Routine to return the next entry in the domain alias list.
156
157  when we are a PDC or BDC, then unix groups that are explicitly NOT mapped
158  to aliases are treated as DOMAIN groups (see groupunix.c).
159
160  when we are a member of a domain (not a PDC or BDC) then unix groups
161  that are explicitly NOT mapped to aliases (map_alias_gid) are treated
162  as LOCAL groups.
163
164  the reasoning behind this is to make it as simple as possible (not an easy
165  task) for people to set up a domain-aware samba server, in each role that
166  the server can take.
167
168  *************************************************************************/
169 static LOCAL_GRP *getalsunixpwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem)
170 {
171         /* Static buffers we will return. */
172         static LOCAL_GRP gp_buf;
173         struct group *unix_grp = NULL;
174         struct unix_entries *grps = (struct unix_entries *)vp;
175
176         if (lp_server_role() == ROLE_DOMAIN_NONE)
177         {
178                 /*
179                  * no domain role, no domain aliases (or domain groups,
180                  * but that's dealt with by groupdb...).
181                  */
182
183                 return NULL;
184         }
185
186         aldb_init_als(&gp_buf);
187
188         /* get array of unix names + gids.  this function does NOT
189            get a copy of the unix group members
190          */
191
192         /* cycle through unix groups */
193         for (; grps->grp_idx < grps->num_grps; grps->grp_idx++)
194         {
195                 DOM_NAME_MAP gmep;
196                 fstring sid_str;
197
198                 unix_grp = &grps->grps[grps->grp_idx];
199
200                 DEBUG(10,("getgrpunixpwent: enum unix group entry %s\n",
201                            unix_grp->gr_name));
202                         
203                 if (!lookupsmbgrpgid(unix_grp->gr_gid, &gmep))
204                 {
205                         continue;
206                 }
207
208                 sid_to_string(sid_str, &gmep.sid);
209                 DEBUG(10,("group %s found, sid %s type %d\n",
210                         gmep.nt_name, sid_str, gmep.type));
211
212                 if (gmep.type != SID_NAME_ALIAS)
213                 {
214                         continue;
215                 }
216
217                 sid_split_rid(&gmep.sid, &gp_buf.rid);
218                 if (!sid_equal(&global_sam_sid, &gmep.sid))
219                 {
220                         continue;
221                 }
222
223                 fstrcpy(gp_buf.name, gmep.nt_name);
224                 break;
225         }
226
227         if (unix_grp == NULL || grps->grp_idx >= grps->num_grps)
228         {
229                 return NULL;
230         }
231
232         /* get the user's domain aliases.  there are a maximum of 32 */
233
234         if (mem != NULL && num_mem != NULL)
235         {
236                 (*mem) = NULL;
237                 (*num_mem) = 0;
238
239                 unix_grp = getgrgid(unix_grp->gr_gid);
240                 get_unixalias_members(unix_grp, num_mem, mem);
241         }
242
243         {
244                 pstring linebuf;
245                 make_alias_line(linebuf, sizeof(linebuf), &gp_buf, mem, num_mem);
246                 DEBUG(10,("line: '%s'\n", linebuf));
247         }
248
249         grps->grp_idx++; /* advance so next enum gets next entry */
250         return &gp_buf;
251 }
252
253 /************************************************************************
254  Routine to add an entry to the alspasswd file.
255 *************************************************************************/
256
257 static BOOL add_alsunixgrp_entry(LOCAL_GRP *newals)
258 {
259         DEBUG(0, ("add_alsunixgrp_entry: NOT IMPLEMENTED\n"));
260         return False;
261 }
262
263 /************************************************************************
264  Routine to search the alspasswd file for an entry matching the aliasname.
265  and then modify its alias entry. 
266 ************************************************************************/
267
268 static BOOL mod_alsunixgrp_entry(LOCAL_GRP* als)
269 {
270         DEBUG(0, ("mod_alsunixgrp_entry: NOT IMPLEMENTED\n"));
271         return False;
272 }
273
274 /************************************************************************
275  Routine to search the grppasswd file for an entry matching the rid.
276  and then delete it.
277 ************************************************************************/
278
279 static BOOL del_alsunixgrp_entry(uint32 rid)
280 {
281         DEBUG(0, ("del_alsunixgrp_entry: NOT IMPLEMENTED\n"));
282         return False;
283 }
284
285 /************************************************************************
286  Routine to add a member to an entry to the grppasswd file.
287 *************************************************************************/
288 static BOOL add_alsunixgrp_member(uint32 rid, DOM_SID *member_sid)
289 {
290         DEBUG(0, ("add_alsunixgrp_member: NOT IMPLEMENTED\n"));
291         return False;
292 }
293
294 /************************************************************************
295  Routine to delete a member from an entry to the grppasswd file.
296 *************************************************************************/
297 static BOOL del_alsunixgrp_member(uint32 rid, DOM_SID *member_sid)
298 {
299         DEBUG(0, ("del_alsunixgrp_member: NOT IMPLEMENTED\n"));
300         return False;
301 }
302
303
304 static struct aliasdb_ops unix_ops =
305 {
306         startalsunixpwent,
307         endalsunixpwent,
308         getalsunixpwpos,
309         setalsunixpwpos,
310
311         iterate_getaliasntnam,          /* In aliasdb.c */
312         iterate_getaliasgid,          /* In aliasdb.c */
313         iterate_getaliasrid,          /* In aliasdb.c */
314         getalsunixpwent,
315
316         add_alsunixgrp_entry,
317         mod_alsunixgrp_entry,
318         del_alsunixgrp_entry,
319
320         add_alsunixgrp_member,
321         del_alsunixgrp_member,
322
323         iterate_getuseraliasntnam      /* in aliasdb.c */
324 };
325
326 struct aliasdb_ops *unix_initialise_alias_db(void)
327 {    
328         return &unix_ops;
329 }
330
331 #else
332  /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
333  void unix_alspass_dummy_function(void) { } /* stop some compilers complaining */
334 #endif /* USE_SMBPASS_DB */