correctly initiazlize idmap tdb when creationg new
[samba.git] / source / sam / idmap_util.c
1 /* 
2    Unix SMB/CIFS implementation.
3    ID Mapping
4    Copyright (C) Simo Sorce 2003
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/
19
20 #include "includes.h"
21
22 #undef DBGC_CLASS
23 #define DBGC_CLASS DBGC_IDMAP
24
25
26 /******************************************************************
27  * Get the free RID base if idmap is configured, otherwise return 0
28  ******************************************************************/
29
30 uint32 idmap_get_free_rid_base(void)
31 {
32         uint32 low, high;
33         if (idmap_get_free_rid_range(&low, &high)) {
34                 return low;
35         }
36         return 0;
37 }
38
39 BOOL idmap_check_ugid_is_in_free_range(uint32 id)
40 {
41         uint32 low, high;
42
43         if (!idmap_get_free_ugid_range(&low, &high)) {
44                 return False;
45         }
46         if (id < low || id > high) {
47                 return False;
48         }
49         return True;
50 }
51
52 BOOL idmap_check_rid_is_in_free_range(uint32 rid)
53 {
54         uint32 low, high;
55
56         if (!idmap_get_free_rid_range(&low, &high)) {
57                 return False;
58         }
59         if (rid < low || rid > high) {
60                 return False;
61         }
62         return True;
63 }
64
65 /******************************************************************
66  * Get the the non-algorithmic RID range if idmap range are defined
67  ******************************************************************/
68
69 BOOL idmap_get_free_rid_range(uint32 *low, uint32 *high)
70 {
71         uint32 id_low, id_high;
72
73         if (lp_idmap_only()) {
74                 *low = BASE_RID;
75                 *high = (uint32)-1;
76         }
77
78         if (!idmap_get_free_ugid_range(&id_low, &id_high)) {
79                 return False;
80         }
81
82         *low = fallback_pdb_uid_to_user_rid(id_low);
83         if (fallback_pdb_user_rid_to_uid((uint32)-1) < id_high) {
84                 *high = (uint32)-1;
85         } else {
86                 *high = fallback_pdb_uid_to_user_rid(id_high);
87         }
88
89         return True;
90 }
91
92 BOOL idmap_get_free_ugid_range(uint32 *low, uint32 *high)
93 {
94         uid_t u_low, u_high;
95         gid_t g_low, g_high;
96
97         if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
98                 return False;
99         }
100         if (u_low < g_low) {
101                 *low = u_low;
102         } else {
103                 *low = g_low;
104         }
105         if (u_high < g_high) {
106                 *high = g_high;
107         } else {
108                 *high = u_high;
109         }
110         return True;
111 }
112
113 /*****************************************************************
114  *THE CANONICAL* convert uid_t to SID function.
115  Tries winbind first - then uses local lookup.
116  Returns SID pointer.
117 *****************************************************************/  
118
119 DOM_SID *uid_to_sid(DOM_SID *sid, uid_t uid)
120 {
121         unid_t id;
122
123         DEBUG(10,("uid_to_sid: uid = [%d]\n", uid));
124
125         if (idmap_check_ugid_is_in_free_range(uid)) {
126                 id.uid = uid;
127                 if (NT_STATUS_IS_ERR(idmap_get_sid_from_id(sid, id, ID_USERID))) {
128                         DEBUG(10, ("uid_to_sid: Failed to map sid = [%s]\n", sid_string_static(sid)));
129                         return NULL;
130                 }
131         } else {
132                 sid_copy(sid, get_global_sam_sid());
133                 sid_append_rid(sid, fallback_pdb_uid_to_user_rid(uid));
134                 
135                 DEBUG(10,("uid_to_sid: algorithmic %u -> %s\n", (unsigned int)uid, sid_string_static(sid)));
136         }
137         return sid;
138         
139 }
140
141 /*****************************************************************
142  *THE CANONICAL* convert gid_t to SID function.
143  Tries winbind first - then uses local lookup.
144  Returns SID pointer.
145 *****************************************************************/  
146
147 DOM_SID *gid_to_sid(DOM_SID *sid, gid_t gid)
148 {
149         GROUP_MAP map;
150         unid_t id;
151
152         DEBUG(10,("gid_to_sid: gid = [%d]\n", gid));
153
154         if (idmap_check_ugid_is_in_free_range(gid)) {
155                 id.gid = gid;
156                 if (NT_STATUS_IS_ERR(idmap_get_sid_from_id(sid, id, ID_GROUPID))) {
157                         DEBUG(10, ("gid_to_sid: Failed to map sid = [%s]\n", sid_string_static(sid)));
158                         return NULL;
159                 }
160         } else {
161                 if (pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) {
162                         sid_copy(sid, &map.sid);
163                 } else {
164                         sid_copy(sid, get_global_sam_sid());
165                         sid_append_rid(sid, pdb_gid_to_group_rid(gid));
166                 }
167
168                 DEBUG(10,("gid_to_sid: algorithmic %u -> %s\n", (unsigned int)gid, sid_string_static(sid)));
169         }
170
171         return sid;
172 }
173
174 /*****************************************************************
175  *THE CANONICAL* convert SID to uid function.
176  Tries winbind first - then uses local lookup.
177  Returns True if this name is a user sid and the conversion
178  was done correctly, False if not. sidtype is set by this function.
179 *****************************************************************/  
180
181 BOOL sid_to_uid(const DOM_SID *sid, uid_t *uid)
182 {
183         uint32 rid;
184         unid_t id;
185         int type;
186
187         DEBUG(10,("sid_to_uid: sid = [%s]\n", sid_string_static(sid)));
188
189         if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) {
190                 if (!idmap_check_rid_is_in_free_range(rid)) {
191                         if (!fallback_pdb_rid_is_user(rid)) {
192                                 DEBUG(3, ("sid_to_uid: RID %u is *NOT* a user\n", (unsigned)rid));
193                                 return False;
194                         }
195                         *uid = fallback_pdb_user_rid_to_uid(rid);
196                         return True;
197                 }
198         }
199
200         type = ID_USERID;
201         if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &type, sid))) {
202                 DEBUG(10,("sid_to_uid: uid = [%d]\n", id.uid));
203                 *uid = id.uid;
204                 return True;
205         }
206
207         return False;
208 }
209
210 /*****************************************************************
211  *THE CANONICAL* convert SID to gid function.
212  Tries winbind first - then uses local lookup.
213  Returns True if this name is a user sid and the conversion
214  was done correctly, False if not.
215 *****************************************************************/  
216
217 BOOL sid_to_gid(const DOM_SID *sid, gid_t *gid)
218 {
219         uint32 rid;
220         unid_t id;
221         int type;
222
223         DEBUG(10,("sid_to_gid: sid = [%s]\n", sid_string_static(sid)));
224
225         if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) {
226                 GROUP_MAP map;
227                 BOOL result;
228
229                 if (pdb_getgrsid(&map, *sid, MAPPING_WITHOUT_PRIV)) {
230                         /* the SID is in the mapping table but not mapped */
231                         if (map.gid==(gid_t)-1)
232                                 return False;
233                         
234                         *gid = map.gid;
235                         return True;
236                 } else {
237                         if (!idmap_check_rid_is_in_free_range(rid)) {
238                                 if (fallback_pdb_rid_is_user(rid)) {
239                                         DEBUG(3, ("sid_to_gid: RID %u is *NOT* a group\n", (unsigned)rid));
240                                         return False;
241                                 }
242                                 *gid = pdb_group_rid_to_gid(rid);
243                                 return True;
244                         }
245                 }
246         }
247
248         type = ID_GROUPID;
249         if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &type, sid))) {
250                 DEBUG(10,("sid_to_gid: gid = [%d]\n", id.gid));
251                 *gid = id.gid;
252                 return True;
253         }
254
255         return False;
256 }
257