builtin alias password API
[samba.git] / source / groupdb / builtindb.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Pasesword and authentication handling
5    Copyright (C) Jeremy Allison 1996-1998
6    Copyright (C) Luke Kenneth Caseson Leighton 1996-1998
7       
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.
12    
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.
17    
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 Mases Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "nterr.h"
25
26 extern int DEBUGLEVEL;
27
28 extern fstring global_sam_name;
29 extern DOM_SID global_sam_sid;
30
31 /*
32  * NOTE. All these functions are abstracted into a structure
33  * that points to the correct function for the selected database. JRA.
34  */
35
36 static struct aliasdb_ops *bidb_ops = NULL;
37
38 /***************************************************************
39  Initialise the builtin db operations.
40 ***************************************************************/
41
42 BOOL initialise_builtin_db(void)
43 {
44   if (bidb_ops)
45   {
46     return True;
47   }
48
49 #ifdef WITH_NISPLUS
50   bidb_ops =  nisplus_initialise_builtin_db();
51 #elif defined(WITH_LDAP)
52   bidb_ops = ldap_initialise_builtin_db();
53 #elif defined(USE_SMBUNIX_DB)
54   bidb_ops = unix_initialise_builtin_db();
55 #endif 
56
57   return (bidb_ops != NULL);
58 }
59
60 /*
61  * Functions that return/manipulate a LOCAL_GRP.
62  */
63
64 /************************************************************************
65  Utility function to search builtin database by gid: the LOCAL_GRP
66  structure does not have a gid member, so we have to convert here
67  from gid to builtin rid.
68 *************************************************************************/
69 LOCAL_GRP *iterate_getbuiltingid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem)
70 {
71         DOM_NAME_MAP gmep;
72         uint32 rid;
73         if (!lookupsmbgrpgid(gid, &gmep))
74         {
75                 DEBUG(0,("iterate_getbuiltingid: gid %d does not map to one of our Domain's Aliases\n", gid));
76                 return NULL;
77         }
78
79         if (gmep.type != SID_NAME_ALIAS )
80         {
81                 DEBUG(0,("iterate_getbuiltingid: gid %d does not map to one of our Domain's Aliases\n", gid));
82                 return NULL;
83         }
84
85         sid_split_rid(&gmep.sid, &rid);
86         if (!sid_equal(&gmep.sid, &global_sam_sid))
87         {
88                 DEBUG(0,("iterate_getbuiltingid: gid %d does not map into our Domain SID\n", gid));
89                 return NULL;
90         }
91
92         return iterate_getbuiltinrid(rid, mem, num_mem);
93 }
94
95 /************************************************************************
96  Utility function to search builtin database by rid.  use this if your database
97  does not have search facilities.
98 *************************************************************************/
99 LOCAL_GRP *iterate_getbuiltinrid(uint32 rid, LOCAL_GRP_MEMBER **mem, int *num_mem)
100 {
101         LOCAL_GRP *blt = NULL;
102         void *fp = NULL;
103
104         DEBUG(10, ("search by rid: 0x%x\n", rid));
105
106         /* Open the builtin database file - not for update. */
107         fp = startbuiltinent(False);
108
109         if (fp == NULL)
110         {
111                 DEBUG(0, ("unable to open builtin database.\n"));
112                 return NULL;
113         }
114
115         while ((blt = getbuiltinent(fp, mem, num_mem)) != NULL && blt->rid != rid)
116         {
117                 DEBUG(10,("iterate: %s 0x%x", blt->name, blt->rid));
118         }
119
120         if (blt != NULL)
121         {
122                 DEBUG(10, ("found builtin %s by rid: 0x%x\n", blt->name, rid));
123         }
124
125         endbuiltinent(fp);
126         return blt;
127 }
128
129 /************************************************************************
130  Utility function to search builtin database by name.  use this if your database
131  does not have search facilities.
132 *************************************************************************/
133 LOCAL_GRP *iterate_getbuiltinntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
134 {
135         LOCAL_GRP *blt = NULL;
136         void *fp = NULL;
137
138         DEBUG(10, ("search by name: %s\n", name));
139
140         /* Open the builtin database file - not for update. */
141         fp = startbuiltinent(False);
142
143         if (fp == NULL)
144         {
145                 DEBUG(0, ("unable to open builtin database.\n"));
146                 return NULL;
147         }
148
149         while ((blt = getbuiltinent(fp, mem, num_mem)) != NULL && !strequal(blt->name, name))
150         {
151         }
152
153         if (blt != NULL)
154         {
155                 DEBUG(10, ("found by name: %s\n", name));
156         }
157
158         endbuiltinent(fp);
159         return blt;
160 }
161
162 /*************************************************************************
163  Routine to return the next entry in the smbdomainbuiltin list.
164  *************************************************************************/
165 BOOL add_domain_builtin(LOCAL_GRP **blts, int *num_blts, LOCAL_GRP *blt)
166 {
167         if (blts == NULL || num_blts == NULL || blt == NULL)
168         {
169                 return False;
170         }
171
172         (*blts) = Realloc((*blts), ((*num_blts)+1) * sizeof(LOCAL_GRP));
173         if ((*blts) == NULL)
174         {
175                 return False;
176         }
177
178         DEBUG(10,("adding builtin %s(%s)\n", blt->name, blt->comment));
179
180         fstrcpy((*blts)[(*num_blts)].name   , blt->name);
181         fstrcpy((*blts)[(*num_blts)].comment, blt->comment);
182         (*blts)[(*num_blts)].rid = blt->rid;
183
184         (*num_blts)++;
185
186         return True;
187 }
188
189 /*************************************************************************
190  checks to see if a user is a member of a domain builtin
191  *************************************************************************/
192 static BOOL user_is_member(const char *user_name, LOCAL_GRP_MEMBER *mem, int num_mem)
193 {
194         int i;
195         pstring name;
196         slprintf(name, sizeof(name)-1, "%s\\%s", global_sam_name, user_name);
197
198         for (i = 0; i < num_mem; i++)
199         {
200                 DEBUG(10,("searching against user %s...\n", mem[i].name));
201                 if (strequal(mem[i].name, name))
202                 {
203                         DEBUG(10,("searching for user %s: found\n", name));
204                         return True;
205                 }
206         }
207         DEBUG(10,("searching for user %s: not found\n", name));
208         return False;
209 }
210
211 /*************************************************************************
212  gets an array of builtin aliases that a user is in.  use this if your database
213  does not have search facilities
214  *************************************************************************/
215 BOOL iterate_getuserbuiltinntnam(const char *user_name, LOCAL_GRP **blts, int *num_blts)
216 {
217         LOCAL_GRP *blt = NULL;
218         LOCAL_GRP_MEMBER *mem = NULL;
219         int num_mem = 0;
220         void *fp = NULL;
221
222         DEBUG(10, ("search for userbuiltin by name: %s\n", user_name));
223
224         if (user_name == NULL || blts == NULL || num_blts == NULL)
225         {
226                 return False;
227         }
228
229         (*blts) = NULL;
230         (*num_blts) = 0;
231
232         /* Open the builtin database file - not for update. */
233         fp = startbuiltinent(False);
234
235         if (fp == NULL)
236         {
237                 DEBUG(0, ("unable to open builtin database.\n"));
238                 return False;
239         }
240
241         /* iterate through all builtin aliases.  search members for required user */
242         while ((blt = getbuiltinent(fp, &mem, &num_mem)) != NULL)
243         {
244                 DEBUG(5,("builtin name %s members: %d\n", blt->name, num_mem));
245                 if (num_mem != 0 && mem != NULL)
246                 {
247                         BOOL ret = True;
248                         if (user_is_member(user_name, mem, num_mem))
249                         {
250                                 ret = add_domain_builtin(blts, num_blts, blt);
251                         }
252
253                         free(mem);
254                         mem = NULL;
255                         num_mem = 0;
256
257                         if (!ret)
258                         {
259                                 (*num_blts) = 0;
260                                 break;
261                         }
262                 }
263         }
264
265         if ((*num_blts) != 0)
266         {
267                 DEBUG(10, ("found %d user builtin aliases:\n", (*num_blts)));
268         }
269
270         endbuiltinent(fp);
271         return True;
272 }
273
274 /*************************************************************************
275  gets an array of builtin aliases that a user is in.  use this if your database
276  does not have search facilities
277  *************************************************************************/
278 BOOL enumdombuiltins(LOCAL_GRP **blts, int *num_blts)
279 {
280         LOCAL_GRP *blt = NULL;
281         void *fp = NULL;
282
283         DEBUG(10, ("enum user builtin aliases\n"));
284
285         if (blts == NULL || num_blts == NULL)
286         {
287                 return False;
288         }
289
290         (*blts) = NULL;
291         (*num_blts) = 0;
292
293         /* Open the builtin database file - not for update. */
294         fp = startbuiltinent(False);
295
296         if (fp == NULL)
297         {
298                 DEBUG(0, ("unable to open builtin database.\n"));
299                 return False;
300         }
301
302         /* iterate through all builtin aliases. */
303         while ((blt = getbuiltinent(fp, NULL, NULL)) != NULL)
304         {
305                 if (!add_domain_builtin(blts, num_blts, blt))
306                 {
307                         DEBUG(0,("unable to add builtin while enumerating\n"));
308                         return False;
309                 }
310         }
311
312         if ((*num_blts) != 0)
313         {
314                 DEBUG(10, ("found %d user builtin aliases:\n", (*num_blts)));
315         }
316
317         endbuiltinent(fp);
318         return True;
319 }
320
321 /***************************************************************
322  Start to enumerate the builtin database list. Returns a void pointer
323  to ensure no modification outside this module.
324 ****************************************************************/
325
326 void *startbuiltinent(BOOL update)
327 {
328   return bidb_ops->startaliasent(update);
329 }
330
331 /***************************************************************
332  End enumeration of the builtin database list.
333 ****************************************************************/
334
335 void endbuiltinent(void *vp)
336 {
337   bidb_ops->endaliasent(vp);
338 }
339
340 /*************************************************************************
341  Routine to return the next entry in the builtin database list.
342  *************************************************************************/
343
344 LOCAL_GRP *getbuiltinent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem)
345 {
346         return bidb_ops->getaliasent(vp, mem, num_mem);
347 }
348
349 /************************************************************************
350  Routine to add an entry to the builtin database file.
351 *************************************************************************/
352
353 BOOL add_builtin_entry(LOCAL_GRP *newblt)
354 {
355         return bidb_ops->add_alias_entry(newblt);
356 }
357
358 /************************************************************************
359  Routine to search the builtin database file for an entry matching the builtinname.
360  and then replace the entry.
361 ************************************************************************/
362
363 BOOL mod_builtin_entry(LOCAL_GRP* blt)
364 {
365         return bidb_ops->mod_alias_entry(blt);
366 }
367
368 /************************************************************************
369  Routine to search builtin database by name.
370 *************************************************************************/
371
372 LOCAL_GRP *getbuiltinntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
373 {
374         return bidb_ops->getaliasntnam(name, mem, num_mem);
375 }
376
377 /************************************************************************
378  Routine to search builtin database by builtin rid.
379 *************************************************************************/
380
381 LOCAL_GRP *getbuiltinrid(uint32 builtin_rid, LOCAL_GRP_MEMBER **mem, int *num_mem)
382 {
383         return bidb_ops->getaliasrid(builtin_rid, mem, num_mem);
384 }
385
386 /************************************************************************
387  Routine to search builtin database by gid.
388 *************************************************************************/
389
390 LOCAL_GRP *getbuiltingid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem)
391 {
392         return bidb_ops->getaliasgid(gid, mem, num_mem);
393 }
394
395 /*************************************************************************
396  gets an array of builtin aliases that a user is in.
397  *************************************************************************/
398 BOOL getuserbuiltinntnam(const char *user_name, LOCAL_GRP **blt, int *num_blts)
399 {
400         return bidb_ops->getuseraliasntnam(user_name, blt, num_blts);
401 }
402
403 /*************************************************************
404  initialises a LOCAL_GRP.
405  **************************************************************/
406 void bidb_init_blt(LOCAL_GRP *blt)
407 {
408         if (blt == NULL) return;
409         ZERO_STRUCTP(blt);
410 }
411
412 /*************************************************************
413  turns an builtin entry into a string.
414  **************************************************************/
415 BOOL make_builtin_line(char *p, int max_len,
416                                 LOCAL_GRP *blt,
417                                 LOCAL_GRP_MEMBER **mem, int *num_mem)
418 {
419         int i;
420         int len;
421         len = slprintf(p, max_len-1, "%s:%s:%d:", blt->name, blt->comment, blt->rid);
422
423         if (len == -1)
424         {
425                 DEBUG(0,("make_builtin_line: cannot create entry\n"));
426                 return False;
427         }
428
429         p += len;
430         max_len -= len;
431
432         if (mem == NULL || num_mem == NULL)
433         {
434                 return True;
435         }
436
437         for (i = 0; i < (*num_mem); i++)
438         {
439                 len = strlen((*mem)[i].name);
440                 p = safe_strcpy(p, (*mem)[i].name, max_len); 
441
442                 if (p == NULL)
443                 {
444                         DEBUG(0, ("make_builtin_line: out of space for builtin aliases!\n"));
445                         return False;
446                 }
447
448                 max_len -= len;
449
450                 if (i != (*num_mem)-1)
451                 {
452                         *p = ',';
453                         p++;
454                         max_len--;
455                 }
456         }
457
458         return True;
459 }