preparing for release of alpha-2.6
[Samba/gbeck.git] / source / groupdb / groupdb.c
blobbfb3a254e6a27306c4615f4cc9d2f8174de0ffd6
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Password and authentication handling
5 Copyright (C) Jeremy Allison 1996-1998
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1998
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
24 #include "nterr.h"
25 #include "sids.h"
27 extern int DEBUGLEVEL;
30 * NOTE. All these functions are abstracted into a structure
31 * that points to the correct function for the selected database. JRA.
34 static struct groupdb_ops *gpdb_ops = NULL;
36 /***************************************************************
37 Initialise the group db operations.
38 ***************************************************************/
40 BOOL initialise_group_db(void)
42 if (gpdb_ops)
44 return True;
47 #ifdef WITH_NISPLUS
48 gpdb_ops = nisplus_initialise_group_db();
49 #elif defined(WITH_NT5LDAP)
50 gpdb_ops = nt5ldap_initialise_group_db();
51 #elif defined(WITH_LDAP)
52 gpdb_ops = ldap_initialise_group_db();
53 #elif defined(USE_SMBUNIX_DB)
54 gpdb_ops = unix_initialise_group_db();
55 #endif
57 return (gpdb_ops != NULL);
61 * Functions that return/manipulate a DOMAIN_GRP.
64 /************************************************************************
65 Utility function to search group database by gid: the DOMAIN_GRP
66 structure does not have a gid member, so we have to convert here
67 from gid to group rid.
68 *************************************************************************/
69 DOMAIN_GRP *iterate_getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
71 DOM_NAME_MAP gmep;
72 uint32 rid;
73 if (!lookupsmbgrpgid(gid, &gmep))
75 DEBUG(0,("iterate_getgroupgid: gid %d does not map to one of our Domain's Groups\n", gid));
76 return NULL;
79 if (gmep.type != SID_NAME_DOM_GRP && gmep.type != SID_NAME_WKN_GRP)
81 DEBUG(0,("iterate_getgroupgid: gid %d does not map to one of our Domain's Groups\n", gid));
82 return NULL;
85 sid_split_rid(&gmep.sid, &rid);
86 if (!sid_equal(&gmep.sid, &global_sam_sid))
88 DEBUG(0,("iterate_getgroupgid: gid %d does not map into our Domain SID\n", gid));
89 return NULL;
92 return iterate_getgrouprid(rid, mem, num_mem);
95 /************************************************************************
96 Utility function to search group database by rid. use this if your database
97 does not have search facilities.
98 *************************************************************************/
99 DOMAIN_GRP *iterate_getgrouprid(uint32 rid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
101 DOMAIN_GRP *grp = NULL;
102 void *fp = NULL;
104 DEBUG(10, ("search by rid: 0x%x\n", rid));
106 /* Open the group database file - not for update. */
107 fp = startgroupent(False);
109 if (fp == NULL)
111 DEBUG(0, ("unable to open group database.\n"));
112 return NULL;
115 while ((grp = getgroupent(fp, mem, num_mem)) != NULL && grp->rid != rid)
119 if (grp != NULL)
121 DEBUG(10, ("found group %s by rid: 0x%x\n", grp->name, rid));
124 endgroupent(fp);
125 return grp;
128 /************************************************************************
129 Utility function to search group database by name. use this if your database
130 does not have search facilities.
131 *************************************************************************/
132 DOMAIN_GRP *iterate_getgroupntnam(const char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
134 DOMAIN_GRP *grp = NULL;
135 void *fp = NULL;
137 DEBUG(10, ("search by name: %s\n", name));
139 /* Open the group database file - not for update. */
140 fp = startgroupent(False);
142 if (fp == NULL)
144 DEBUG(0, ("unable to open group database.\n"));
145 return NULL;
148 while ((grp = getgroupent(fp, mem, num_mem)) != NULL && !strequal(grp->name, name))
152 if (grp != NULL)
154 DEBUG(10, ("found by name: %s\n", name));
157 endgroupent(fp);
158 return grp;
161 /*************************************************************************
162 Routine to return the next entry in the smbdomaingroup list.
163 *************************************************************************/
164 BOOL add_domain_group(DOMAIN_GRP **grps, int *num_grps, DOMAIN_GRP *grp)
166 if (grps == NULL || num_grps == NULL || grp == NULL)
168 return False;
171 (*grps) = Realloc((*grps), ((*num_grps)+1) * sizeof(DOMAIN_GRP));
172 if ((*grps) == NULL)
174 return False;
177 DEBUG(10,("adding group %s(%s)\n", grp->name, grp->comment));
179 fstrcpy((*grps)[(*num_grps)].name , grp->name);
180 fstrcpy((*grps)[(*num_grps)].comment, grp->comment);
181 (*grps)[(*num_grps)].attr = grp->attr;
182 (*grps)[(*num_grps)].rid = grp->rid ;
184 (*num_grps)++;
186 return True;
189 /*************************************************************************
190 checks to see if a user is a member of a domain group
191 *************************************************************************/
192 static BOOL user_is_member(const char *user_name, DOMAIN_GRP_MEMBER *mem, int num_mem)
194 int i;
195 for (i = 0; i < num_mem; i++)
197 DEBUG(10,("searching against user %s...\n", mem[i].name));
198 if (strequal(mem[i].name, user_name))
200 DEBUG(10,("searching for user %s: found\n", user_name));
201 return True;
204 DEBUG(10,("searching for user %s: not found\n", user_name));
205 return False;
208 /*************************************************************************
209 gets an array of groups that a user is in. use this if your database
210 does not have search facilities
211 *************************************************************************/
212 BOOL iterate_getusergroupsnam(const char *user_name, DOMAIN_GRP **grps, int *num_grps)
214 DOMAIN_GRP *grp = NULL;
215 DOMAIN_GRP_MEMBER *mem = NULL;
216 int num_mem = 0;
217 void *fp = NULL;
219 DEBUG(10, ("search for usergroups by name: %s\n", user_name));
221 if (user_name == NULL || grps == NULL || num_grps == NULL)
223 return False;
226 (*grps) = NULL;
227 (*num_grps) = 0;
229 /* Open the group database file - not for update. */
230 fp = startgroupent(False);
232 if (fp == NULL)
234 DEBUG(0, ("unable to open group database.\n"));
235 return False;
238 /* iterate through all groups. search members for required user */
239 while ((grp = getgroupent(fp, &mem, &num_mem)) != NULL)
241 DEBUG(5,("group name %s members: %d\n", grp->name, num_mem));
242 if (num_mem != 0 && mem != NULL)
244 BOOL ret = True;
245 if (user_is_member(user_name, mem, num_mem))
247 ret = add_domain_group(grps, num_grps, grp);
250 free(mem);
251 mem = NULL;
252 num_mem = 0;
254 if (!ret)
256 (*num_grps) = 0;
257 break;
262 if ((*num_grps) != 0)
264 DEBUG(10, ("found %d user groups:\n", (*num_grps)));
267 endgroupent(fp);
268 return True;
271 /*************************************************************************
272 gets an array of groups that a user is in. use this if your database
273 does not have search facilities
274 *************************************************************************/
275 BOOL enumdomgroups(DOMAIN_GRP **grps, int *num_grps)
277 DOMAIN_GRP *grp = NULL;
278 void *fp = NULL;
280 DEBUG(10, ("enum user groups\n"));
282 if (grps == NULL || num_grps == NULL)
284 return False;
287 (*grps) = NULL;
288 (*num_grps) = 0;
290 /* Open the group database file - not for update. */
291 fp = startgroupent(False);
293 if (fp == NULL)
295 DEBUG(0, ("unable to open group database.\n"));
296 return False;
299 /* iterate through all groups. */
300 while ((grp = getgroupent(fp, NULL, NULL)) != NULL)
302 if (!add_domain_group(grps, num_grps, grp))
304 DEBUG(0,("unable to add group while enumerating\n"));
305 return False;
309 if ((*num_grps) != 0)
311 DEBUG(10, ("found %d user groups:\n", (*num_grps)));
314 endgroupent(fp);
315 return True;
318 /***************************************************************
319 Start to enumerate the group database list. Returns a void pointer
320 to ensure no modification outside this module.
321 ****************************************************************/
323 void *startgroupent(BOOL update)
325 return gpdb_ops->startgroupent(update);
328 /***************************************************************
329 End enumeration of the group database list.
330 ****************************************************************/
332 void endgroupent(void *vp)
334 gpdb_ops->endgroupent(vp);
337 /*************************************************************************
338 Routine to return the next entry in the group database list.
339 *************************************************************************/
341 DOMAIN_GRP *getgroupent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem)
343 return gpdb_ops->getgroupent(vp, mem, num_mem);
346 /************************************************************************
347 Routine to add an entry to the group database file.
348 on entry, the entry is added by name.
349 on exit, the RID is expected to have been set.
350 *************************************************************************/
352 BOOL add_group_entry(DOMAIN_GRP *newgrp)
354 BOOL ret;
355 if (newgrp->rid != 0xffffffff)
357 DEBUG(0,("add_group_entry - RID must be 0xffffffff, \
358 database instance is responsible for allocating the RID, not you.\n"));
359 return False;
361 ret = gpdb_ops->add_group_entry(newgrp);
362 if (newgrp->rid == 0xffffffff)
364 DEBUG(0,("add_group_entry - RID has not been set by database\n"));
365 return False;
367 return ret;
370 /************************************************************************
371 Routine to delete group database entry matching by rid.
372 ************************************************************************/
373 BOOL del_group_entry(uint32 rid)
375 return gpdb_ops->del_group_entry(rid);
378 /************************************************************************
379 Routine to search group database file for entry matching by rid or groupname.
380 and then replace the entry.
381 ************************************************************************/
383 BOOL mod_group_entry(DOMAIN_GRP* grp)
385 return gpdb_ops->mod_group_entry(grp);
388 /************************************************************************
389 Routine to add a member to an entry in the group database file.
390 *************************************************************************/
391 BOOL add_group_member(uint32 rid, uint32 member_rid)
393 return gpdb_ops->add_group_member(rid, member_rid);
396 /************************************************************************
397 Routine to delete a member from an entry in the group database file.
398 *************************************************************************/
399 BOOL del_group_member(uint32 rid, uint32 member_rid)
401 return gpdb_ops->del_group_member(rid, member_rid);
404 /************************************************************************
405 Routine to search group database by name.
406 *************************************************************************/
408 DOMAIN_GRP *getgroupntnam(const char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
410 return gpdb_ops->getgroupntnam(name, mem, num_mem);
413 /************************************************************************
414 Routine to search group database by group rid.
415 *************************************************************************/
417 DOMAIN_GRP *getgrouprid(uint32 group_rid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
419 return gpdb_ops->getgrouprid(group_rid, mem, num_mem);
422 /************************************************************************
423 Routine to search group database by gid.
424 *************************************************************************/
426 DOMAIN_GRP *getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
428 return gpdb_ops->getgroupgid(gid, mem, num_mem);
431 /*************************************************************************
432 gets an array of groups that a user is in.
433 *************************************************************************/
434 BOOL getusergroupsntnam(const char *user_name, DOMAIN_GRP **grp, int *num_grps)
436 return gpdb_ops->getusergroupsntnam(user_name, grp, num_grps);
439 /*************************************************************
440 initialises a DOMAIN_GRP.
441 **************************************************************/
443 void gpdb_init_grp(DOMAIN_GRP *grp)
445 if (grp == NULL) return;
446 ZERO_STRUCTP(grp);
449 /*************************************************************************
450 turns a list of groups into a string.
451 *************************************************************************/
452 BOOL make_group_line(char *p, int max_len,
453 DOMAIN_GRP *grp,
454 DOMAIN_GRP_MEMBER **mem, int *num_mem)
456 int i;
457 int len;
458 len = slprintf(p, max_len-1, "%s:%s:%d:", grp->name, grp->comment, grp->rid);
460 if (len == -1)
462 DEBUG(0,("make_group_line: cannot create entry\n"));
463 return False;
466 p += len;
467 max_len -= len;
469 if (mem == NULL || num_mem == NULL)
471 return True;
474 for (i = 0; i < (*num_mem); i++)
476 len = strlen((*mem)[i].name);
477 p = safe_strcpy(p, (*mem)[i].name, max_len);
479 if (p == NULL)
481 DEBUG(0, ("make_group_line: out of space for groups!\n"));
482 return False;
485 max_len -= len;
487 if (i != (*num_mem)-1)
489 *p = ',';
490 p++;
491 max_len--;
495 return True;