f2a530cbb95fe534d7af2d58cad145a99755ced1
[samba.git] / source3 / groupdb / builtinldap.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.0.
4    LDAP builtin group database for SAMBA
5    Copyright (C) Matthew Chapman 1998
6    
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.
11    
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.
16    
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.
20    
21 */
22
23 #include "includes.h"
24
25 #ifdef WITH_LDAP
26
27 #include <lber.h>
28 #include <ldap.h>
29
30 extern int DEBUGLEVEL;
31
32 /* Internal state */
33 extern LDAP *ldap_struct;
34 extern LDAPMessage *ldap_results;
35 extern LDAPMessage *ldap_entry;
36
37 /* Static structure filled for requests */
38 static LOCAL_GRP localgrp;
39
40
41 /***************************************************************
42   Get group and membership information.
43  ****************************************************************/
44
45 static LOCAL_GRP *ldapbuiltin_getgrp(LOCAL_GRP *group,
46                      LOCAL_GRP_MEMBER **members, int *num_membs)
47 {
48         fstring temp;
49         char **values;
50         LOCAL_GRP_MEMBER *memblist;
51         char *value, *sep;
52         int i;
53
54         if(!ldap_entry)
55                 return NULL;
56
57         if(!ldap_get_attribute("cn", group->name)) {
58                 DEBUG(0, ("Missing cn\n"));
59                 return NULL; }
60         
61         DEBUG(2,("Retrieving alias [%s]\n", group->name));
62
63         if(ldap_get_attribute("rid", temp)) {
64                 group->rid = atoi(temp);
65         } else {
66                 DEBUG(0, ("Missing rid\n"));
67                 return NULL;
68         }
69
70         if(!ldap_get_attribute("description", group->comment))
71                 group->comment[0] = 0;
72
73         if(!members || !num_membs) {
74                 ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
75                 return group;
76         }
77
78         if(values = ldap_get_values(ldap_struct, ldap_entry, "member")) {
79
80                 *num_membs = i = ldap_count_values(values);
81                 *members = memblist = malloc(i * sizeof(LOCAL_GRP_MEMBER));
82
83                 do {
84                         value = values[--i];
85
86                         if(!(sep = strchr(value, ','))) {
87                                 DEBUG(0, ("Malformed alias member\n"));
88                                 return NULL;
89                         }
90                         *(sep++) = 0;
91                         fstrcpy(memblist[i].name, value);
92
93                         if(!(value = strchr(sep, ','))) {
94                                 DEBUG(0, ("Malformed alias member\n"));
95                                 return NULL;
96                         }
97                         *(value++) = 0;
98                         string_to_sid(&memblist[i].sid, sep);
99
100                         if((memblist[i].sid_use = atoi(value))
101                                         >= SID_NAME_UNKNOWN)
102                                 DEBUG(0, ("Invalid SID use in alias"));
103
104                 } while(i > 0);
105
106                 ldap_value_free(values);
107
108         } else {
109                 *num_membs = 0;
110                 *members = NULL;
111         }
112
113         return group;
114 }
115
116
117 /************************************************************************
118   Queues the necessary modifications to save a LOCAL_GRP structure
119  ************************************************************************/
120
121 static void ldapbuiltin_grpmods(LOCAL_GRP *group, LDAPMod ***mods,
122                         int operation)
123 {
124         fstring temp;
125
126         *mods = NULL;
127
128         if(operation == LDAP_MOD_ADD) { /* immutable attributes */
129                 ldap_make_mod(mods, LDAP_MOD_ADD, "objectClass", "sambaBuiltin");
130                 ldap_make_mod(mods, LDAP_MOD_ADD, "cn", group->name);
131
132                 slprintf(temp, sizeof(temp)-1, "%d", (gid_t)(-1));
133                 ldap_make_mod(mods, LDAP_MOD_ADD, "gidNumber", temp);
134
135                 slprintf(temp, sizeof(temp)-1, "%d", group->rid);
136                 ldap_make_mod(mods, LDAP_MOD_ADD, "rid", temp);
137         }
138
139         ldap_make_mod(mods, operation, "description", group->comment);
140 }
141
142
143 /***************************************************************
144   Begin/end smbgrp enumeration.
145  ****************************************************************/
146
147 static void *ldapbuiltin_enumfirst(BOOL update)
148 {
149         if (lp_server_role() == ROLE_DOMAIN_NONE)
150                 return NULL;
151
152         if (!ldap_open_connection(False))
153                 return NULL;
154
155         ldap_search_for("objectClass=sambaBuiltin");
156
157         return ldap_struct;
158 }
159
160 static void ldapbuiltin_enumclose(void *vp)
161 {
162         ldap_close_connection();
163 }
164
165
166 /*************************************************************************
167   Save/restore the current position in a query
168  *************************************************************************/
169
170 static SMB_BIG_UINT ldapbuiltin_getdbpos(void *vp)
171 {
172         return (SMB_BIG_UINT)((ulong)ldap_entry);
173 }
174
175 static BOOL ldapbuiltin_setdbpos(void *vp, SMB_BIG_UINT tok)
176 {
177         ldap_entry = (LDAPMessage *)((ulong)tok);
178         return (True);
179 }
180
181
182 /*************************************************************************
183   Return limited smb_passwd information, and group membership.
184  *************************************************************************/
185
186 static LOCAL_GRP *ldapbuiltin_getgrpbynam(const char *name,
187                LOCAL_GRP_MEMBER **members, int *num_membs)
188 {
189         fstring filter;
190         LOCAL_GRP *ret;
191
192         if(!ldap_open_connection(False))
193                 return (False);
194
195         slprintf(filter, sizeof(filter)-1,
196                  "(&(cn=%s)(objectClass=sambaBuiltin))", name);
197         ldap_search_for(filter);
198
199         ret = ldapbuiltin_getgrp(&localgrp, members, num_membs);
200
201         ldap_close_connection();
202         return ret;
203 }
204
205 static LOCAL_GRP *ldapbuiltin_getgrpbygid(gid_t grp_id,
206                LOCAL_GRP_MEMBER **members, int *num_membs)
207 {
208         fstring filter;
209         LOCAL_GRP *ret;
210
211         if(!ldap_open_connection(False))
212                 return (False);
213
214         slprintf(filter, sizeof(filter)-1,
215                  "(&(gidNumber=%d)(objectClass=sambaBuiltin))", grp_id);
216         ldap_search_for(filter);
217         ret = ldapbuiltin_getgrp(&localgrp, members, num_membs);
218
219         ldap_close_connection();
220         return ret;
221 }
222
223 static LOCAL_GRP *ldapbuiltin_getgrpbyrid(uint32 grp_rid,
224                LOCAL_GRP_MEMBER **members, int *num_membs)
225 {
226         fstring filter;
227         LOCAL_GRP *ret;
228
229         if(!ldap_open_connection(False))
230                 return (False);
231
232         slprintf(filter, sizeof(filter)-1,
233                  "(&(rid=%d)(objectClass=sambaBuiltin))", grp_rid);
234         ldap_search_for(filter);
235         ret = ldapbuiltin_getgrp(&localgrp, members, num_membs);
236
237         ldap_close_connection();
238         return ret;
239 }
240
241 static LOCAL_GRP *ldapbuiltin_getcurrentgrp(void *vp,
242                LOCAL_GRP_MEMBER **members, int *num_membs)
243 {
244         return ldapbuiltin_getgrp(&localgrp, members, num_membs);
245 }
246
247 static BOOL ldapbuiltin_addgrp(LOCAL_GRP *group)
248 {
249         LDAPMod **mods;
250
251         ldapbuiltin_grpmods(group, &mods, LDAP_MOD_ADD); 
252         return ldap_makemods("cn", group->name, mods, True);
253 }
254
255 static BOOL ldapbuiltin_modgrp(LOCAL_GRP *group)
256 {
257         LDAPMod **mods;
258
259         ldapbuiltin_grpmods(group, &mods, LDAP_MOD_REPLACE);
260         return ldap_makemods("cn", group->name, mods, False);
261 }
262
263 static BOOL ldapbuiltin_getusergroups(const char *name,
264                         LOCAL_GRP **groups, int *num_grps)
265 {
266         LOCAL_GRP *grouplist;
267         fstring filter;
268         int i;
269
270         slprintf(filter, sizeof(pstring)-1,
271                  "(&(member=%s,*)(objectclass=sambaBuiltin))", name);
272         ldap_search_for(filter);
273
274         *num_grps = i = ldap_count_entries(ldap_struct, ldap_results);
275
276         if(!i) {
277                 *groups = NULL;
278                 return (True);
279         }
280
281         *groups = grouplist = malloc(i * sizeof(LOCAL_GRP));
282         do {
283                 i--;
284         } while(ldapbuiltin_getgrp(&grouplist[i], NULL, NULL) && (i > 0));
285
286         return (True);
287 }
288
289
290 static struct aliasdb_ops ldapbuiltin_ops =
291 {
292         ldapbuiltin_enumfirst,
293         ldapbuiltin_enumclose,
294         ldapbuiltin_getdbpos,
295         ldapbuiltin_setdbpos,
296
297         ldapbuiltin_getgrpbynam,
298         ldapbuiltin_getgrpbygid,
299         ldapbuiltin_getgrpbyrid,
300         ldapbuiltin_getcurrentgrp,
301
302         ldapbuiltin_addgrp,
303         ldapbuiltin_modgrp,
304
305         ldapbuiltin_getusergroups
306 };
307
308 struct aliasdb_ops *ldap_initialise_builtin_db(void)
309 {
310         return &ldapbuiltin_ops;
311 }
312
313 #else
314  void builtinldap_dummy_function(void);
315  void builtinldap_dummy_function(void) { } /* stop some compilers complaining */
316 #endif
317