35f386cbf8bf4e6e8b31c7ac6431c4cfd34ca1a1
[samba.git] / source / groupdb / groupunix.c
1 /*
2  * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
3  * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
4  * 
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License as published by the Free
7  * Software Foundation; either version 2 of the License, or (at your option)
8  * any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  * 
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 675
17  * Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #include "includes.h"
21
22 #ifdef USE_SMBUNIX_DB
23
24 extern int DEBUGLEVEL;
25
26
27 extern DOM_SID global_sam_sid;
28
29 /***************************************************************
30  Start to enumerate the grppasswd list. Returns a void pointer
31  to ensure no modification outside this module.
32 ****************************************************************/
33
34 static void *startgrpunixpwent(BOOL update)
35 {
36         setgrent();
37         return (void*)(-1);
38 }
39
40 /***************************************************************
41  End enumeration of the grppasswd list.
42 ****************************************************************/
43
44 static void endgrpunixpwent(void *vp)
45 {
46         endgrent();
47 }
48
49 /*************************************************************************
50  Return the current position in the grppasswd list as an SMB_BIG_UINT.
51  This must be treated as an opaque token.
52 *************************************************************************/
53 static SMB_BIG_UINT getgrpunixpwpos(void *vp)
54 {
55         return (SMB_BIG_UINT)0;
56 }
57
58 /*************************************************************************
59  Set the current position in the grppasswd list from an SMB_BIG_UINT.
60  This must be treated as an opaque token.
61 *************************************************************************/
62 static BOOL setgrpunixpwpos(void *vp, SMB_BIG_UINT tok)
63 {
64         return False;
65 }
66
67 /*************************************************************************
68  Routine to return the next entry in the smbdomaingroup list.
69  *************************************************************************/
70 BOOL get_unixgroup_members(struct group *grp,
71                                 int *num_mem, DOMAIN_GRP_MEMBER **members)
72 {
73         int i;
74         char *unix_name;
75
76         if (num_mem == NULL || members == NULL)
77         {
78                 return False;
79         }
80
81         (*num_mem) = 0;
82         (*members) = NULL;
83
84         for (i = 0; (unix_name = grp->gr_mem[i]) != NULL; i++)
85         {
86                 DOM_NAME_MAP gmep;
87                 DOMAIN_GRP_MEMBER *mem;
88                 uint32 rid;
89
90                 if (!lookupsmbpwnam (unix_name, &gmep) &&
91                     !lookupsmbgrpnam(unix_name, &gmep))
92                 {
93                         continue;
94                 }
95
96                 if (gmep.type != SID_NAME_DOM_GRP &&
97                     gmep.type != SID_NAME_USER &&
98                     gmep.type != SID_NAME_WKN_GRP)
99                 {
100                         DEBUG(0,("group database: name %s is not in a Domain Group\n",
101                                   unix_name));
102                         continue;
103                 }
104                         
105                 sid_split_rid(&gmep.sid, &rid);
106                 if (!sid_equal(&global_sam_sid, &gmep.sid))
107                 {
108                         DEBUG(0,("group database: could not resolve name %s (wrong Domain SID)\n",
109                                   unix_name));
110                         continue;
111                 }
112
113                 (*members) = Realloc((*members), ((*num_mem)+1) * sizeof(DOMAIN_GRP_MEMBER));
114                 if ((*members) == NULL)
115                 {
116                         return False;
117                 }
118
119                 mem = &(*members)[(*num_mem)];
120                 (*num_mem)++;
121
122                 fstrcpy(mem->name, gmep.nt_name);
123                 mem->attr    = 0x07;
124                 mem->sid_use = gmep.type;
125                 mem->rid     = rid;
126         }
127         return True;
128 }
129
130 /*************************************************************************
131  Routine to return the next entry in the domain group list.
132
133  if we are not a PDC or BDC, then we do NOT support Domain groups, only
134  aliases.  try running MUSRMGR.EXE or running USRMGR.EXE selected on a
135  workstation, you will find that no Domain groups are listed: only aliases.
136
137  so, as a PDC or BDC, all unix groups not explicitly mapped using
138  map_group_gid() are treated as Domain groups.
139
140  *************************************************************************/
141 static DOMAIN_GRP *getgrpunixpwent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem)
142 {
143         /* Static buffers we will return. */
144         static DOMAIN_GRP gp_buf;
145         struct group *unix_grp;
146
147         if (lp_server_role() == ROLE_DOMAIN_NONE || 
148             lp_server_role() == ROLE_DOMAIN_MEMBER)
149         {
150                 /*
151                  * only PDC and BDC have domain groups in the SAM.
152                  * (however as member of domain you can have LOCAL groups,
153                  * but that's dealt with in the aliasdb...)
154                  */
155
156                 return NULL;
157         }
158
159         gpdb_init_grp(&gp_buf);
160
161         fstrcpy(gp_buf.comment, "");
162         gp_buf.attr    = 0x07;
163
164         /* cycle through unix groups */
165         while ((unix_grp = getgrent()) != NULL)
166         {
167                 DOM_NAME_MAP gmep;
168                 DEBUG(10,("getgrpunixpwent: enum unix group entry %s\n",
169                            unix_grp->gr_name));
170                         
171                 if (!lookupsmbgrpgid(unix_grp->gr_gid, &gmep))
172                 {
173                         continue;
174                 }
175
176                 if (gmep.type != SID_NAME_DOM_GRP &&
177                     gmep.type != SID_NAME_WKN_GRP)
178                 {
179                         continue;
180                 }
181
182                 sid_split_rid(&gmep.sid, &gp_buf.rid);
183                 if (!sid_equal(&gmep.sid, &global_sam_sid))
184                 {
185                         continue;
186                 }
187
188                 fstrcpy(gp_buf.name, gmep.nt_name);
189                 break;
190         }
191
192         if (unix_grp == NULL)
193         {
194                 return NULL;
195         }
196
197         /* get the user's domain groups.  there are a maximum of 32 */
198
199         if (mem != NULL && num_mem != NULL)
200         {
201                 (*mem) = NULL;
202                 (*num_mem) = 0;
203
204                 get_unixgroup_members(unix_grp, num_mem, mem);
205         }
206
207         {
208                 pstring linebuf;
209                 make_group_line(linebuf, sizeof(linebuf), &gp_buf, mem, num_mem);
210                 DEBUG(10,("line: '%s'\n", linebuf));
211         }
212
213         return &gp_buf;
214 }
215
216 /************************************************************************
217  Routine to add an entry to the grppasswd file.
218 *************************************************************************/
219
220 static BOOL add_grpunixgrp_entry(DOMAIN_GRP *newgrp)
221 {
222         DEBUG(0, ("add_grpunixgrp_entry: NOT IMPLEMENTED\n"));
223         return False;
224 }
225
226 /************************************************************************
227  Routine to search database for entry matching the groupname and/or rid.
228  and then modify its group entry. 
229 ************************************************************************/
230
231 static BOOL mod_grpunixgrp_entry(DOMAIN_GRP* grp)
232 {
233         DEBUG(0, ("mod_grpunixgrp_entry: NOT IMPLEMENTED\n"));
234         return False;
235 }
236
237 /************************************************************************
238  Routine to search the grppasswd file for an entry matching the rid.
239  and then delete it.
240 ************************************************************************/
241
242 static BOOL del_grpunixgrp_entry(uint32 rid)
243 {
244         DEBUG(0, ("del_grpunixgrp_entry: NOT IMPLEMENTED\n"));
245         return False;
246 }
247
248 /************************************************************************
249  Routine to add a member to an entry to the grppasswd file.
250 *************************************************************************/
251 static BOOL add_grpunixgrp_member(uint32 rid, uint32 member_rid)
252 {
253         DEBUG(0, ("add_grpunixgrp_member: NOT IMPLEMENTED\n"));
254         return False;
255 }
256
257 /************************************************************************
258  Routine to delete a member from an entry to the grppasswd file.
259 *************************************************************************/
260 static BOOL del_grpunixgrp_member(uint32 rid, uint32 member_rid)
261 {
262         DEBUG(0, ("del_grpunixgrp_member: NOT IMPLEMENTED\n"));
263         return False;
264 }
265
266 static struct groupdb_ops unix_ops =
267 {
268         startgrpunixpwent,
269         endgrpunixpwent,
270         getgrpunixpwpos,
271         setgrpunixpwpos,
272
273         iterate_getgroupntnam,          /* In groupdb.c */
274         iterate_getgroupgid,          /* In groupdb.c */
275         iterate_getgrouprid,          /* In groupdb.c */
276         getgrpunixpwent,
277
278         add_grpunixgrp_entry,
279         mod_grpunixgrp_entry,
280         del_grpunixgrp_entry,
281
282         add_grpunixgrp_member,
283         del_grpunixgrp_member,
284
285         iterate_getusergroupsnam      /* in groupdb.c */
286 };
287
288 struct groupdb_ops *unix_initialise_group_db(void)
289 {    
290         return &unix_ops;
291 }
292
293 #else
294  /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
295  void unix_grppass_dummy_function(void) { } /* stop some compilers complaining */
296 #endif /* USE_SMBPASS_DB */