2 Unix SMB/Netbios implementation.
4 LDAP domain group database for SAMBA
5 Copyright (C) Matthew Chapman 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.
30 extern int DEBUGLEVEL;
31 extern DOM_SID global_sam_sid;
34 extern LDAP *ldap_struct;
35 extern LDAPMessage *ldap_results;
36 extern LDAPMessage *ldap_entry;
38 /* Static structure filled for requests */
39 static DOMAIN_GRP domgrp;
42 /***************************************************************
43 Get group and membership information.
44 ****************************************************************/
46 static DOMAIN_GRP *ldapgroup_getgrp(DOMAIN_GRP *group,
47 DOMAIN_GRP_MEMBER **members, int *num_membs)
51 DOMAIN_GRP_MEMBER *memblist;
58 if(!ldap_get_attribute("cn", group->name)) {
59 DEBUG(0, ("Missing cn\n"));
62 DEBUG(2,("Retrieving group [%s]\n", group->name));
64 if(ldap_get_attribute("rid", temp)) {
65 group->rid = strtol(temp, NULL, 16);
67 DEBUG(0, ("Missing rid\n"));
71 if(!ldap_get_attribute("description", group->comment))
72 group->comment[0] = 0;
76 if(!members || !num_membs) {
77 ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
81 if(values = ldap_get_values(ldap_struct, ldap_entry, "member")) {
83 *num_membs = i = ldap_count_values(values);
84 *members = memblist = malloc(i * sizeof(DOMAIN_GRP_MEMBER));
89 if(!(sep = strchr(value, ','))) {
90 DEBUG(0, ("Malformed group member\n"));
94 fstrcpy(memblist[i].name, value);
96 if(!(value = strchr(sep, ','))) {
97 DEBUG(0, ("Malformed group member\n"));
100 memblist[i].rid = strtol(sep, &value, 16);
102 if((memblist[i].sid_use = atoi(value+1))
104 DEBUG(0, ("Invalid SID use in group"));
106 memblist[i].attr = 0x7;
110 ldap_value_free(values);
117 ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
122 /************************************************************************
123 Queues the necessary modifications to save a DOMAIN_GRP structure
124 ************************************************************************/
126 static void ldapgroup_grpmods(DOMAIN_GRP *group, LDAPMod ***mods,
133 if(operation == LDAP_MOD_ADD) { /* immutable attributes */
134 ldap_make_mod(mods, LDAP_MOD_ADD, "objectClass", "sambaGroup");
135 ldap_make_mod(mods, LDAP_MOD_ADD, "cn", group->name);
137 slprintf(temp, sizeof(temp)-1, "%x", group->rid);
138 ldap_make_mod(mods, LDAP_MOD_ADD, "rid", temp);
141 ldap_make_mod(mods, operation, "description", group->comment);
145 /************************************************************************
146 Create a group member entry
147 ************************************************************************/
149 static BOOL ldapgroup_memmods(uint32 user_rid, LDAPMod ***mods, int operation)
156 sid_copy(&sid, &global_sam_sid);
157 sid_append_rid(&sid, user_rid);
158 if (lookup_sid(&sid, name, &type))
161 slprintf(member, sizeof(member)-1, "%s,%x,%d", name, user_rid, type);
164 ldap_make_mod(mods, operation, "member", member);
169 /***************************************************************
170 Begin/end domain group enumeration.
171 ****************************************************************/
173 static void *ldapgroup_enumfirst(BOOL update)
175 int server_role = lp_server_role();
177 if (server_role == ROLE_DOMAIN_NONE ||
178 server_role == ROLE_DOMAIN_MEMBER)
184 ldap_search_for("objectclass=sambaGroup");
189 static void ldapgroup_enumclose(void *vp)
195 /*************************************************************************
196 Save/restore the current position in a query
197 *************************************************************************/
199 static SMB_BIG_UINT ldapgroup_getdbpos(void *vp)
201 return (SMB_BIG_UINT)((ulong)ldap_entry);
204 static BOOL ldapgroup_setdbpos(void *vp, SMB_BIG_UINT tok)
206 ldap_entry = (LDAPMessage *)((ulong)tok);
211 /*************************************************************************
212 Return information about domain groups and their members.
213 *************************************************************************/
215 static DOMAIN_GRP *ldapgroup_getgrpbynam(const char *name,
216 DOMAIN_GRP_MEMBER **members, int *num_membs)
224 slprintf(filter, sizeof(filter)-1,
225 "(&(cn=%s)(objectClass=sambaGroup))", name);
226 ldap_search_for(filter);
228 ret = ldapgroup_getgrp(&domgrp, members, num_membs);
234 static DOMAIN_GRP *ldapgroup_getgrpbygid(gid_t grp_id,
235 DOMAIN_GRP_MEMBER **members, int *num_membs)
243 slprintf(filter, sizeof(filter)-1,
244 "(&(gidNumber=%d)(objectClass=sambaGroup))", grp_id);
245 ldap_search_for(filter);
247 ret = ldapgroup_getgrp(&domgrp, members, num_membs);
253 static DOMAIN_GRP *ldapgroup_getgrpbyrid(uint32 grp_rid,
254 DOMAIN_GRP_MEMBER **members, int *num_membs)
262 slprintf(filter, sizeof(filter)-1,
263 "(&(rid=%x)(objectClass=sambaGroup))", grp_rid);
264 ldap_search_for(filter);
266 ret = ldapgroup_getgrp(&domgrp, members, num_membs);
272 static DOMAIN_GRP *ldapgroup_getcurrentgrp(void *vp,
273 DOMAIN_GRP_MEMBER **members, int *num_membs)
275 return ldapgroup_getgrp(&domgrp, members, num_membs);
279 /*************************************************************************
280 Add/modify/delete domain groups.
281 *************************************************************************/
283 static BOOL ldapgroup_addgrp(DOMAIN_GRP *group)
287 if (!ldap_allocaterid(&group->rid))
289 DEBUG(0,("RID generation failed\n"));
293 ldapgroup_grpmods(group, &mods, LDAP_MOD_ADD);
294 return ldap_makemods("cn", group->name, mods, True);
297 static BOOL ldapgroup_modgrp(DOMAIN_GRP *group)
301 ldapgroup_grpmods(group, &mods, LDAP_MOD_REPLACE);
302 return ldap_makemods("cn", group->name, mods, False);
305 static BOOL ldapgroup_delgrp(uint32 grp_rid)
314 slprintf(filter, sizeof(filter)-1,
315 "(&(rid=%x)(objectClass=sambaGroup))", grp_rid);
316 ldap_search_for(filter);
318 if (!ldap_entry || !(dn = ldap_get_dn(ldap_struct, ldap_entry)))
324 err = ldap_delete_s(ldap_struct, dn);
328 if (err != LDAP_SUCCESS)
330 DEBUG(0, ("delete: %s\n", ldap_err2string(err)));
338 /*************************************************************************
339 Add users to/remove users from groups.
340 *************************************************************************/
342 static BOOL ldapgroup_addmem(uint32 grp_rid, uint32 user_rid)
347 slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid);
349 if(!ldapgroup_memmods(user_rid, &mods, LDAP_MOD_ADD))
352 return ldap_makemods("rid", rid_str, mods, False);
355 static BOOL ldapgroup_delmem(uint32 grp_rid, uint32 user_rid)
360 slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid);
362 if(!ldapgroup_memmods(user_rid, &mods, LDAP_MOD_DELETE))
365 return ldap_makemods("rid", rid_str, mods, False);
369 /*************************************************************************
370 Return domain groups that a user is in.
371 *************************************************************************/
373 static BOOL ldapgroup_getusergroups(const char *name, DOMAIN_GRP **groups,
376 DOMAIN_GRP *grouplist;
383 slprintf(filter, sizeof(pstring)-1,
384 "(&(member=%s,*)(objectclass=sambaGroup))", name);
385 ldap_search_for(filter);
387 *num_grps = i = ldap_count_entries(ldap_struct, ldap_results);
395 *groups = grouplist = malloc(i * sizeof(DOMAIN_GRP));
398 } while(ldapgroup_getgrp(&grouplist[i], NULL, NULL) && (i > 0));
405 static struct groupdb_ops ldapgroup_ops =
412 ldapgroup_getgrpbynam,
413 ldapgroup_getgrpbygid,
414 ldapgroup_getgrpbyrid,
415 ldapgroup_getcurrentgrp,
424 ldapgroup_getusergroups
427 struct groupdb_ops *ldap_initialise_group_db(void)
429 return &ldapgroup_ops;
433 void groupldap_dummy_function(void);
434 void groupldap_dummy_function(void) { } /* stop some compilers complaining */