35d810dabc23cd40b471d3f701313c6e652b8205
[samba.git] / source / groupdb / aliasldap.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.0.
4    LDAP local 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 *ldapalias_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 ldapalias_grpmods(LOCAL_GRP *group, LDAPMod ***mods, int operation)
122 {
123         fstring temp;
124
125         *mods = NULL;
126
127         if(operation == LDAP_MOD_ADD) { /* immutable attributes */
128                 ldap_make_mod(mods, LDAP_MOD_ADD, "objectClass", "sambaAlias");
129                 ldap_make_mod(mods, LDAP_MOD_ADD, "cn", group->name);
130
131                 slprintf(temp, sizeof(temp)-1, "%d", (gid_t)(-1));
132                 ldap_make_mod(mods, LDAP_MOD_ADD, "gidNumber", temp);
133
134                 slprintf(temp, sizeof(temp)-1, "%d", group->rid);
135                 ldap_make_mod(mods, LDAP_MOD_ADD, "rid", temp);
136         }
137
138         ldap_make_mod(mods, operation, "description", group->comment);
139 }
140
141
142 /***************************************************************
143   Begin/end smbgrp enumeration.
144  ****************************************************************/
145
146 static void *ldapalias_enumfirst(BOOL update)
147 {
148         if (lp_server_role() == ROLE_DOMAIN_NONE)
149                 return NULL;
150
151         if (!ldap_open_connection(False))
152                 return NULL;
153
154         ldap_search_for("objectClass=sambaAlias");
155
156         return ldap_struct;
157 }
158
159 static void ldapalias_enumclose(void *vp)
160 {
161         ldap_close_connection();
162 }
163
164
165 /*************************************************************************
166   Save/restore the current position in a query
167  *************************************************************************/
168
169 static SMB_BIG_UINT ldapalias_getdbpos(void *vp)
170 {
171         return (SMB_BIG_UINT)((ulong)ldap_entry);
172 }
173
174 static BOOL ldapalias_setdbpos(void *vp, SMB_BIG_UINT tok)
175 {
176         ldap_entry = (LDAPMessage *)((ulong)tok);
177         return (True);
178 }
179
180
181 /*************************************************************************
182   Return limited smb_passwd information, and group membership.
183  *************************************************************************/
184
185 static LOCAL_GRP *ldapalias_getgrpbynam(const char *name,
186                LOCAL_GRP_MEMBER **members, int *num_membs)
187 {
188         fstring filter;
189         LOCAL_GRP *ret;
190
191         if(!ldap_open_connection(False))
192                 return (False);
193
194         slprintf(filter, sizeof(filter)-1,
195                  "(&(cn=%s)(objectClass=sambaAlias))", name);
196         ldap_search_for(filter);
197
198         ret = ldapalias_getgrp(&localgrp, members, num_membs);
199
200         ldap_close_connection();
201         return ret;
202 }
203
204 static LOCAL_GRP *ldapalias_getgrpbygid(gid_t grp_id,
205                LOCAL_GRP_MEMBER **members, int *num_membs)
206 {
207         fstring filter;
208         LOCAL_GRP *ret;
209
210         if(!ldap_open_connection(False))
211                 return (False);
212
213         slprintf(filter, sizeof(filter)-1,
214                  "(&(gidNumber=%d)(objectClass=sambaAlias))", grp_id);
215         ldap_search_for(filter);
216         ret = ldapalias_getgrp(&localgrp, members, num_membs);
217
218         ldap_close_connection();
219         return ret;
220 }
221
222 static LOCAL_GRP *ldapalias_getgrpbyrid(uint32 grp_rid,
223                LOCAL_GRP_MEMBER **members, int *num_membs)
224 {
225         fstring filter;
226         LOCAL_GRP *ret;
227
228         if(!ldap_open_connection(False))
229                 return (False);
230
231         slprintf(filter, sizeof(filter)-1,
232                  "(&(rid=%d)(objectClass=sambaAlias))", grp_rid);
233         ldap_search_for(filter);
234         ret = ldapalias_getgrp(&localgrp, members, num_membs);
235
236         ldap_close_connection();
237         return ret;
238 }
239
240 static LOCAL_GRP *ldapalias_getcurrentgrp(void *vp,
241                LOCAL_GRP_MEMBER **members, int *num_membs)
242 {
243         return ldapalias_getgrp(&localgrp, members, num_membs);
244 }
245
246 static BOOL ldapalias_addgrp(LOCAL_GRP *group)
247 {
248         LDAPMod **mods;
249
250         ldapalias_grpmods(group, &mods, LDAP_MOD_ADD); 
251         return ldap_makemods("cn", group->name, mods, True);
252 }
253
254 static BOOL ldapalias_modgrp(LOCAL_GRP *group)
255 {
256         LDAPMod **mods;
257
258         ldapalias_grpmods(group, &mods, LDAP_MOD_REPLACE);
259         return ldap_makemods("cn", group->name, mods, False);
260 }
261
262 static BOOL ldapalias_getusergroups(const char *name, LOCAL_GRP **groups,
263                                     int *num_grps)
264 {
265         LOCAL_GRP *grouplist;
266         fstring filter;
267         int i;
268
269         slprintf(filter, sizeof(pstring)-1,
270                  "(&(member=%s,*)(objectclass=sambaAlias))", name);
271         ldap_search_for(filter);
272
273         *num_grps = i = ldap_count_entries(ldap_struct, ldap_results);
274
275         if(!i) {
276                 *groups = NULL;
277                 return (True);
278         }
279
280         *groups = grouplist = malloc(i * sizeof(LOCAL_GRP));
281         do {
282                 i--;
283         } while(ldapalias_getgrp(&grouplist[i], NULL, NULL) && (i > 0));
284
285         return (True);
286 }
287
288
289 static struct aliasdb_ops ldapalias_ops =
290 {
291         ldapalias_enumfirst,
292         ldapalias_enumclose,
293         ldapalias_getdbpos,
294         ldapalias_setdbpos,
295
296         ldapalias_getgrpbynam,
297         ldapalias_getgrpbygid,
298         ldapalias_getgrpbyrid,
299         ldapalias_getcurrentgrp,
300
301         ldapalias_addgrp,
302         ldapalias_modgrp,
303
304         ldapalias_getusergroups
305 };
306
307 struct aliasdb_ops *ldap_initialise_alias_db(void)
308 {
309         return &ldapalias_ops;
310 }
311
312 #else
313  void aliasldap_dummy_function(void);
314  void aliasldap_dummy_function(void) { } /* stop some compilers complaining */
315 #endif
316