unix instance of group database API
[samba.git] / source3 / passdb / smbpassgroupunix.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 extern DOM_SID global_member_sid;
26
27 /***************************************************************
28  Start to enumerate the smbpasswd list. Returns a void pointer
29  to ensure no modification outside this module.
30 ****************************************************************/
31
32 static void *startsmbfilegrpent(BOOL update)
33 {
34         return startsmbfilepwent(False);
35 }
36
37 /***************************************************************
38  End enumeration of the smbpasswd list.
39 ****************************************************************/
40
41 static void endsmbfilegrpent(void *vp)
42 {
43         endsmbfilepwent(vp);
44 }
45
46 /*************************************************************************
47  Return the current position in the smbpasswd list as an SMB_BIG_UINT.
48  This must be treated as an opaque token.
49 *************************************************************************/
50
51 static SMB_BIG_UINT getsmbfilegrppos(void *vp)
52 {
53         return getsmbfilepwpos(vp);
54 }
55
56 /*************************************************************************
57  Set the current position in the smbpasswd list from an SMB_BIG_UINT.
58  This must be treated as an opaque token.
59 *************************************************************************/
60
61 static BOOL setsmbfilegrppos(void *vp, SMB_BIG_UINT tok)
62 {
63         return setsmbfilepwpos(vp, tok);
64 }
65
66 /*************************************************************************
67  Routine to return the next smbpassgroup entry
68  *************************************************************************/
69 static struct smb_passwd *getsmbfilegrpent(void *vp,
70                 uint32 **grp_rids, int *num_grps,
71                 uint32 **als_rids, int *num_alss)
72 {
73         /* Static buffers we will return. */
74         struct smb_passwd *pw_buf;
75         struct passwd *pw;
76         int i;
77         int unixgrps;
78         gid_t *grps;
79
80         if (vp == NULL)
81         {
82                 DEBUG(0,("getsmbfilegrpent: Bad password file pointer.\n"));
83                 return NULL;
84         }
85
86         pw_buf = getsmbfilepwent(vp);
87         
88         if (grp_rids != NULL)
89         {
90                 (*grp_rids) = NULL;
91                 (*num_grps) = 0;
92         }
93
94         if (als_rids != NULL)
95         {
96                 (*als_rids) = NULL;
97                 (*num_alss) = 0;
98         }
99         
100         if (als_rids == NULL && grp_rids == NULL)
101         {
102                 return pw_buf;
103         }
104
105         /*
106          * find all unix groups
107          */
108
109         pw = Get_Pwnam(pw_buf->smb_name, False);
110
111         if (pw == NULL)
112         {
113                 return NULL;
114         }
115
116         if (get_unixgroups(pw_buf->smb_name, pw->pw_uid, pw->pw_gid, &unixgrps, &grps))
117         {
118                 return NULL;
119         }
120
121         /*
122          * check each unix group for a mapping as an nt alias or an nt group
123          */
124
125         for (i = 0; i < unixgrps; i++)
126         {
127                 DOM_SID sid;
128                 uint8 type;
129                 char *unix_grpname;
130                 uint32 status;
131                 uint32 rid;
132
133                 /*
134                  * find the unix name for each user's group.
135                  * assume the unix group is an nt name (alias? group? user?)
136                  * (user or not our own domain will be an error).
137                  */
138
139                 unix_grpname = gidtoname(grps[i]);
140                 if (map_unix_alias_name(unix_grpname, &sid, NULL, NULL))
141                 {
142                         /*
143                          * ok, the unix groupname is mapped to an alias.
144                          * check that it is in our domain.
145                          */
146
147                         sid_split_rid(&sid, &rid);
148                         if (!sid_equal(&sid, &global_member_sid))
149                         {
150                                 pstring sid_str;
151                                 sid_to_string(sid_str, &sid);
152                                 DEBUG(0,("user %s is in a UNIX group %s that maps to an NT RID (0x%x) in another domain (%s)\n",
153                                           pw_buf->smb_name, unix_grpname, rid, sid_str));
154                                 continue;
155                         }
156
157                         if (add_num_to_list(als_rids, num_alss, rid) == NULL)
158                         {
159                                 return NULL;
160                         }
161                 }
162                 else if (map_unix_group_name(unix_grpname, &sid, NULL, NULL))
163                 {
164                         /*
165                          * ok, the unix groupname is mapped to a domain group.
166                          * check that it is in our domain.
167                          */
168
169                         sid_split_rid(&sid, &rid);
170                         if (!sid_equal(&sid, &global_member_sid))
171                         {
172                                 pstring sid_str;
173                                 sid_to_string(sid_str, &sid);
174                                 DEBUG(0,("user %s is in a UNIX group %s that maps to an NT RID (0x%x) in another domain (%s)\n",
175                                           pw_buf->smb_name, unix_grpname, rid, sid_str));
176                                 continue;
177                         }
178
179                         if (add_num_to_list(grp_rids, num_grps, rid) == NULL)
180                         {
181                                 return NULL;
182                         }
183                 }
184                 else if (lp_server_role() == ROLE_DOMAIN_MEMBER)
185                 {
186                         /*
187                          * server is a member of a domain or stand-alone.
188                          * name is not explicitly mapped
189                          * so we are responsible for it.
190                          * as a LOCAL group.
191                          */
192
193                         rid = pwdb_gid_to_alias_rid(grps[i]);
194                         if (add_num_to_list(als_rids, num_alss, rid) == NULL)
195                         {
196                                 return NULL;
197                         }
198                 }
199                 else if (lp_server_role() != ROLE_DOMAIN_NONE)
200                 {
201                         /*
202                          * server is a PDC or BDC.
203                          * name is explicitly mapped
204                          * so we are responsible for it.
205                          * as a DOMAIN group.
206                          */
207
208                         rid = pwdb_gid_to_group_rid(grps[i]);
209                         if (add_num_to_list(grp_rids, num_grps, rid) == NULL)
210                         {
211                                 return NULL;
212                         }
213                 }
214         }
215
216         return pw_buf;
217 }
218
219 static struct passgrp_ops file_ops =
220 {
221         startsmbfilegrpent,
222         endsmbfilegrpent,
223         getsmbfilegrppos,
224         setsmbfilegrppos,
225         iterate_getsmbgrpnam,          /* In passgrp.c */
226         iterate_getsmbgrpuid,          /* In passgrp.c */
227         iterate_getsmbgrprid,          /* In passgrp.c */
228         getsmbfilegrpent,
229 };
230
231 struct passgrp_ops *unix_initialise_password_grp(void)
232 {    
233   return &file_ops;
234 }
235
236 #else
237  /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
238  void smbpass_dummy_function(void) { } /* stop some compilers complaining */
239 #endif /* USE_SMBPASS_DB */