2 Unix SMB/Netbios implementation.
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.
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)
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();
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
)
73 if (!lookupsmbgrpgid(gid
, &gmep
))
75 DEBUG(0,("iterate_getgroupgid: gid %d does not map to one of our Domain's Groups\n", gid
));
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
));
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
));
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
;
104 DEBUG(10, ("search by rid: 0x%x\n", rid
));
106 /* Open the group database file - not for update. */
107 fp
= startgroupent(False
);
111 DEBUG(0, ("unable to open group database.\n"));
115 while ((grp
= getgroupent(fp
, mem
, num_mem
)) != NULL
&& grp
->rid
!= rid
)
121 DEBUG(10, ("found group %s by rid: 0x%x\n", grp
->name
, rid
));
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
;
137 DEBUG(10, ("search by name: %s\n", name
));
139 /* Open the group database file - not for update. */
140 fp
= startgroupent(False
);
144 DEBUG(0, ("unable to open group database.\n"));
148 while ((grp
= getgroupent(fp
, mem
, num_mem
)) != NULL
&& !strequal(grp
->name
, name
))
154 DEBUG(10, ("found by name: %s\n", name
));
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
)
171 (*grps
) = Realloc((*grps
), ((*num_grps
)+1) * sizeof(DOMAIN_GRP
));
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
;
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
)
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
));
204 DEBUG(10,("searching for user %s: not found\n", user_name
));
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
;
219 DEBUG(10, ("search for usergroups by name: %s\n", user_name
));
221 if (user_name
== NULL
|| grps
== NULL
|| num_grps
== NULL
)
229 /* Open the group database file - not for update. */
230 fp
= startgroupent(False
);
234 DEBUG(0, ("unable to open group database.\n"));
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
)
245 if (user_is_member(user_name
, mem
, num_mem
))
247 ret
= add_domain_group(grps
, num_grps
, grp
);
262 if ((*num_grps
) != 0)
264 DEBUG(10, ("found %d user groups:\n", (*num_grps
)));
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
;
280 DEBUG(10, ("enum user groups\n"));
282 if (grps
== NULL
|| num_grps
== NULL
)
290 /* Open the group database file - not for update. */
291 fp
= startgroupent(False
);
295 DEBUG(0, ("unable to open group database.\n"));
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"));
309 if ((*num_grps
) != 0)
311 DEBUG(10, ("found %d user groups:\n", (*num_grps
)));
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
)
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"));
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"));
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;
449 /*************************************************************************
450 turns a list of groups into a string.
451 *************************************************************************/
452 BOOL
make_group_line(char *p
, int max_len
,
454 DOMAIN_GRP_MEMBER
**mem
, int *num_mem
)
458 len
= slprintf(p
, max_len
-1, "%s:%s:%d:", grp
->name
, grp
->comment
, grp
->rid
);
462 DEBUG(0,("make_group_line: cannot create entry\n"));
469 if (mem
== NULL
|| num_mem
== NULL
)
474 for (i
= 0; i
< (*num_mem
); i
++)
476 len
= strlen((*mem
)[i
].name
);
477 p
= safe_strcpy(p
, (*mem
)[i
].name
, max_len
);
481 DEBUG(0, ("make_group_line: out of space for groups!\n"));
487 if (i
!= (*num_mem
)-1)