off by one in writing to malloced array. this fixes smbd crash I saw at
[Samba/bb.git] / source / groupdb / groupdb.c
blobd50e4f7322dc5b4e7c7dcea5274c77d7bbae0ca8
1 /*
2 Unix SMB/CIFS implementation.
3 Password and authentication handling
4 Copyright (C) Jeremy Allison 1996-1998
5 Copyright (C) Luke Kenneth Casson Leighton 1996-1998
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 2 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
25 * NOTE. All these functions are abstracted into a structure
26 * that points to the correct function for the selected database. JRA.
29 static struct groupdb_ops *gpdb_ops;
31 /***************************************************************
32 Initialise the group db operations.
33 ***************************************************************/
35 BOOL initialise_group_db(void)
37 if (gpdb_ops)
39 return True;
42 #ifdef WITH_LDAP
43 gpdb_ops = ldap_initialise_group_db();
44 #else
45 gpdb_ops = file_initialise_group_db();
46 #endif
48 return (gpdb_ops != NULL);
52 * Functions that return/manipulate a DOMAIN_GRP.
55 /************************************************************************
56 Utility function to search group database by gid: the DOMAIN_GRP
57 structure does not have a gid member, so we have to convert here
58 from gid to group rid.
59 *************************************************************************/
60 DOMAIN_GRP *iterate_getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
62 return iterate_getgrouprid(pwdb_gid_to_group_rid(gid), mem, num_mem);
65 /************************************************************************
66 Utility function to search group database by rid. use this if your database
67 does not have search facilities.
68 *************************************************************************/
69 DOMAIN_GRP *iterate_getgrouprid(uint32 rid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
71 DOMAIN_GRP *grp = NULL;
72 void *fp = NULL;
74 DEBUG(10, ("search by rid: 0x%x\n", rid));
76 /* Open the group database file - not for update. */
77 fp = startgroupent(False);
79 if (fp == NULL)
81 DEBUG(0, ("unable to open group database.\n"));
82 return NULL;
85 while ((grp = getgroupent(fp, mem, num_mem)) != NULL && grp->rid != rid)
89 if (grp != NULL)
91 DEBUG(10, ("found group %s by rid: 0x%x\n", grp->name, rid));
94 endgroupent(fp);
95 return grp;
98 /************************************************************************
99 Utility function to search group database by name. use this if your database
100 does not have search facilities.
101 *************************************************************************/
102 DOMAIN_GRP *iterate_getgroupnam(char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
104 DOMAIN_GRP *grp = NULL;
105 void *fp = NULL;
107 DEBUG(10, ("search by name: %s\n", name));
109 /* Open the group database file - not for update. */
110 fp = startgroupent(False);
112 if (fp == NULL)
114 DEBUG(0, ("unable to open group database.\n"));
115 return NULL;
118 while ((grp = getgroupent(fp, mem, num_mem)) != NULL && !strequal(grp->name, name))
122 if (grp != NULL)
124 DEBUG(10, ("found by name: %s\n", name));
127 endgroupent(fp);
128 return grp;
131 /*************************************************************************
132 Routine to return the next entry in the smbdomaingroup list.
133 *************************************************************************/
134 BOOL add_domain_group(DOMAIN_GRP **grps, int *num_grps, DOMAIN_GRP *grp)
136 DOMAIN_GRP *tgrps;
138 if (grps == NULL || num_grps == NULL || grp == NULL)
139 return False;
141 tgrps = Realloc((*grps), ((*num_grps)+1) * sizeof(DOMAIN_GRP));
142 if (tgrps == NULL) {
143 SAFE_FREE(*grps);
144 return False;
145 } else
146 (*grps) = tgrps;
148 DEBUG(10,("adding group %s(%s)\n", grp->name, grp->comment));
150 fstrcpy((*grps)[(*num_grps)].name , grp->name);
151 fstrcpy((*grps)[(*num_grps)].comment, grp->comment);
152 (*grps)[(*num_grps)].attr = grp->attr;
153 (*grps)[(*num_grps)].rid = grp->rid ;
155 (*num_grps)++;
157 return True;
160 /*************************************************************************
161 checks to see if a user is a member of a domain group
162 *************************************************************************/
163 static BOOL user_is_member(char *user_name, DOMAIN_GRP_MEMBER *mem, int num_mem)
165 int i;
166 for (i = 0; i < num_mem; i++)
168 DEBUG(10,("searching against user %s...\n", mem[i].name));
169 if (strequal(mem[i].name, user_name))
171 DEBUG(10,("searching for user %s: found\n", user_name));
172 return True;
175 DEBUG(10,("searching for user %s: not found\n", user_name));
176 return False;
179 /*************************************************************************
180 gets an array of groups that a user is in. use this if your database
181 does not have search facilities
182 *************************************************************************/
183 BOOL iterate_getusergroupsnam(char *user_name, DOMAIN_GRP **grps, int *num_grps)
185 DOMAIN_GRP *grp;
186 DOMAIN_GRP_MEMBER *mem = NULL;
187 int num_mem = 0;
188 void *fp = NULL;
190 DEBUG(10, ("search for usergroups by name: %s\n", user_name));
192 if (user_name == NULL || grp == NULL || num_grps == NULL)
194 return False;
197 (*grps) = NULL;
198 (*num_grps) = 0;
200 /* Open the group database file - not for update. */
201 fp = startgroupent(False);
203 if (fp == NULL)
205 DEBUG(0, ("unable to open group database.\n"));
206 return False;
209 /* iterate through all groups. search members for required user */
210 while ((grp = getgroupent(fp, &mem, &num_mem)) != NULL)
212 DEBUG(5,("group name %s members: %d\n", grp->name, num_mem));
213 if (num_mem != 0 && mem != NULL)
215 BOOL ret = True;
216 if (user_is_member(user_name, mem, num_mem))
218 ret = add_domain_group(grps, num_grps, grp);
221 SAFE_FREE(mem);
222 num_mem = 0;
224 if (!ret)
226 (*num_grps) = 0;
227 break;
232 if ((*num_grps) != 0)
234 DEBUG(10, ("found %d user groups:\n", (*num_grps)));
237 endgroupent(fp);
238 return True;
241 /*************************************************************************
242 gets an array of groups that a user is in. use this if your database
243 does not have search facilities
244 *************************************************************************/
245 BOOL enumdomgroups(DOMAIN_GRP **grps, int *num_grps)
247 DOMAIN_GRP *grp;
248 void *fp = NULL;
250 DEBUG(10, ("enum user groups\n"));
252 if (grp == NULL || num_grps == NULL)
254 return False;
257 (*grps) = NULL;
258 (*num_grps) = 0;
260 /* Open the group database file - not for update. */
261 fp = startgroupent(False);
263 if (fp == NULL)
265 DEBUG(0, ("unable to open group database.\n"));
266 return False;
269 /* iterate through all groups. */
270 while ((grp = getgroupent(fp, NULL, NULL)) != NULL)
272 if (!add_domain_group(grps, num_grps, grp))
274 DEBUG(0,("unable to add group while enumerating\n"));
275 return False;
279 if ((*num_grps) != 0)
281 DEBUG(10, ("found %d user groups:\n", (*num_grps)));
284 endgroupent(fp);
285 return True;
288 /***************************************************************
289 Start to enumerate the group database list. Returns a void pointer
290 to ensure no modification outside this module.
291 ****************************************************************/
293 void *startgroupent(BOOL update)
295 return gpdb_ops->startgroupent(update);
298 /***************************************************************
299 End enumeration of the group database list.
300 ****************************************************************/
302 void endgroupent(void *vp)
304 gpdb_ops->endgroupent(vp);
307 /*************************************************************************
308 Routine to return the next entry in the group database list.
309 *************************************************************************/
311 DOMAIN_GRP *getgroupent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem)
313 return gpdb_ops->getgroupent(vp, mem, num_mem);
316 /************************************************************************
317 Routine to add an entry to the group database file.
318 *************************************************************************/
320 BOOL add_group_entry(DOMAIN_GRP *newgrp)
322 return gpdb_ops->add_group_entry(newgrp);
325 /************************************************************************
326 Routine to search the group database file for an entry matching the groupname.
327 and then replace the entry.
328 ************************************************************************/
330 BOOL mod_group_entry(DOMAIN_GRP* grp)
332 return gpdb_ops->mod_group_entry(grp);
335 /************************************************************************
336 Routine to search group database by name.
337 *************************************************************************/
339 DOMAIN_GRP *getgroupnam(char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
341 return gpdb_ops->getgroupnam(name, mem, num_mem);
344 /************************************************************************
345 Routine to search group database by group rid.
346 *************************************************************************/
348 DOMAIN_GRP *getgrouprid(uint32 group_rid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
350 return gpdb_ops->getgrouprid(group_rid, mem, num_mem);
353 /************************************************************************
354 Routine to search group database by gid.
355 *************************************************************************/
357 DOMAIN_GRP *getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
359 return gpdb_ops->getgroupgid(gid, mem, num_mem);
362 /*************************************************************************
363 gets an array of groups that a user is in.
364 *************************************************************************/
365 BOOL getusergroupsnam(char *user_name, DOMAIN_GRP **grp, int *num_grps)
367 return gpdb_ops->getusergroupsnam(user_name, grp, num_grps);
370 /*************************************************************
371 initialises a DOMAIN_GRP.
372 **************************************************************/
374 void gpdb_init_grp(DOMAIN_GRP *grp)
376 if (grp == NULL) return;
377 ZERO_STRUCTP(grp);