0e621cb3cc04668e76ffadd365f9e3a6ab1a0b67
[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 *startsmbunixgrpent(BOOL update)
33 {
34         return startsmbfilepwent(False);
35 }
36
37 /***************************************************************
38  End enumeration of the smbpasswd list.
39 ****************************************************************/
40
41 static void endsmbunixgrpent(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 getsmbunixgrppos(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 setsmbunixgrppos(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 *getsmbunixgrpent(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,("getsmbunixgrpent: 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                 char *unix_grpname;
129                 uint32 status;
130                 uint32 rid;
131
132                 /*
133                  * find the unix name for each user's group.
134                  * assume the unix group is an nt name (alias? group? user?)
135                  * (user or not our own domain will be an error).
136                  */
137
138                 unix_grpname = gidtoname(grps[i]);
139                 if (map_unix_alias_name(unix_grpname, &sid, NULL, NULL))
140                 {
141                         /*
142                          * ok, the unix groupname is mapped to an alias.
143                          * check that it is in our domain.
144                          */
145
146                         sid_split_rid(&sid, &rid);
147                         if (!sid_equal(&sid, &global_member_sid))
148                         {
149                                 pstring sid_str;
150                                 sid_to_string(sid_str, &sid);
151                                 DEBUG(0,("user %s is in a UNIX group %s that maps to an NT Domain Alias RID (0x%x) in another domain (%s)\n",
152                                           pw_buf->smb_name, unix_grpname, rid, sid_str));
153                                 continue;
154                         }
155
156                         if (add_num_to_list(als_rids, num_alss, rid) == NULL)
157                         {
158                                 return NULL;
159                         }
160                 }
161                 else if (map_unix_group_name(unix_grpname, &sid, NULL, NULL))
162                 {
163                         /*
164                          * ok, the unix groupname is mapped to a domain group.
165                          * check that it is in our domain.
166                          */
167
168                         sid_split_rid(&sid, &rid);
169                         if (!sid_equal(&sid, &global_member_sid))
170                         {
171                                 pstring sid_str;
172                                 sid_to_string(sid_str, &sid);
173                                 DEBUG(0,("user %s is in a UNIX group %s that maps to an NT Domain Group RID (0x%x) in another domain (%s)\n",
174                                           pw_buf->smb_name, unix_grpname, rid, sid_str));
175                                 continue;
176                         }
177
178                         if (add_num_to_list(grp_rids, num_grps, rid) == NULL)
179                         {
180                                 return NULL;
181                         }
182                 }
183                 else if (lp_server_role() == ROLE_DOMAIN_MEMBER)
184                 {
185                         /*
186                          * server is a member of a domain or stand-alone.
187                          * name is not explicitly mapped
188                          * so we are responsible for it.
189                          * as a LOCAL group.
190                          */
191
192                         rid = pwdb_gid_to_alias_rid(grps[i]);
193                         if (add_num_to_list(als_rids, num_alss, rid) == NULL)
194                         {
195                                 return NULL;
196                         }
197                 }
198                 else if (lp_server_role() != ROLE_DOMAIN_NONE)
199                 {
200                         /*
201                          * server is a PDC or BDC.
202                          * name is explicitly mapped
203                          * so we are responsible for it.
204                          * as a DOMAIN group.
205                          */
206
207                         rid = pwdb_gid_to_group_rid(grps[i]);
208                         if (add_num_to_list(grp_rids, num_grps, rid) == NULL)
209                         {
210                                 return NULL;
211                         }
212                 }
213         }
214
215         return pw_buf;
216 }
217
218 static struct passgrp_ops file_ops =
219 {
220         startsmbunixgrpent,
221         endsmbunixgrpent,
222         getsmbunixgrppos,
223         setsmbunixgrppos,
224         iterate_getsmbgrpnam,          /* In passgrp.c */
225         iterate_getsmbgrpuid,          /* In passgrp.c */
226         iterate_getsmbgrprid,          /* In passgrp.c */
227         getsmbunixgrpent,
228 };
229
230 struct passgrp_ops *unix_initialise_password_grp(void)
231 {    
232   return &file_ops;
233 }
234
235 #else
236  /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
237  void smbpass_dummy_function(void) { } /* stop some compilers complaining */
238 #endif /* USE_SMBPASS_DB */