2 Unix SMB/Netbios implementation.
5 Winbind daemon - user related function
7 Copyright (C) Tim Potter 2000
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /* High water mark keys */
28 #define HWM_GROUP "GROUP HWM"
29 #define HWM_USER "USER HWM"
33 static TDB_CONTEXT
*idmap_tdb
;
35 /* Allocate either a user or group id from the pool */
37 static BOOL
allocate_id(uid_t
*id
, BOOL isgroup
)
41 /* Get current high water mark */
43 if ((hwm
= tdb_fetch_int(idmap_tdb
,
44 isgroup
? HWM_GROUP
: HWM_USER
)) == -1) {
48 /* Return next available uid in list */
50 if ((isgroup
&& (hwm
> server_state
.gid_high
)) ||
51 (!isgroup
&& (hwm
> server_state
.uid_high
))) {
52 DEBUG(0, ("winbind %sid range full!\n", isgroup
? "g" : "u"));
62 /* Store new high water mark */
64 tdb_store_int(idmap_tdb
, isgroup
? HWM_GROUP
: HWM_USER
, hwm
);
69 /* Get an id from a rid */
71 static BOOL
get_id_from_rid(char *domain_name
, uint32 rid
, uid_t
*id
,
78 /* Check if rid is present in database */
80 slprintf(keystr
, sizeof(keystr
), "%s/%d", domain_name
, rid
);
83 key
.dsize
= strlen(keystr
) + 1;
85 data
= tdb_fetch(idmap_tdb
, key
);
91 /* Parse and return existing uid */
93 fstrcpy(scanstr
, isgroup
? "GID" : "UID");
94 fstrcat(scanstr
, " %d");
96 if (sscanf(data
.dptr
, scanstr
, &the_id
) == 1) {
107 SAFE_FREE(data
.dptr
);
111 /* Allocate a new id for this rid */
113 if (id
&& allocate_id(id
, isgroup
)) {
118 slprintf(keystr2
, sizeof(keystr2
), "%s %d", isgroup
? "GID" :
122 data
.dsize
= strlen(keystr2
) + 1;
124 tdb_store(idmap_tdb
, key
, data
, TDB_REPLACE
);
125 tdb_store(idmap_tdb
, data
, key
, TDB_REPLACE
);
134 /* Get a uid from a user rid */
136 BOOL
winbindd_idmap_get_uid_from_rid(char *domain_name
, uint32 user_rid
,
139 return get_id_from_rid(domain_name
, user_rid
, uid
, False
);
142 /* Get a gid from a group rid */
144 BOOL
winbindd_idmap_get_gid_from_rid(char *domain_name
, uint32 group_rid
,
147 return get_id_from_rid(domain_name
, group_rid
, gid
, True
);
150 BOOL
get_rid_from_id(int id
, uint32
*rid
, struct winbindd_domain
**domain
,
157 slprintf(keystr
, sizeof(keystr
), "%s %d", isgroup
? "GID" : "UID", id
);
160 key
.dsize
= strlen(keystr
) + 1;
162 data
= tdb_fetch(idmap_tdb
, key
);
169 if (next_token(&p
, domain_name
, "/", sizeof(fstring
))) {
178 *domain
= find_domain_from_name(domain_name
);
179 if (*domain
== NULL
) {
180 DEBUG(1, ("unknown domain %s for rid %d\n",
181 domain_name
, the_rid
));
190 SAFE_FREE(data
.dptr
);
196 /* Get a user rid from a uid */
198 BOOL
winbindd_idmap_get_rid_from_uid(uid_t uid
, uint32
*user_rid
,
199 struct winbindd_domain
**domain
)
201 return get_rid_from_id((int)uid
, user_rid
, domain
, False
);
204 /* Get a group rid from a gid */
206 BOOL
winbindd_idmap_get_rid_from_gid(gid_t gid
, uint32
*group_rid
,
207 struct winbindd_domain
**domain
)
209 return get_rid_from_id((int)gid
, group_rid
, domain
, True
);
212 /* Initialise idmap database */
214 BOOL
winbindd_idmap_init(void)
218 if (!(idmap_tdb
= tdb_open_log(lock_path("winbindd_idmap.tdb"), 0,
219 TDB_NOLOCK
, O_RDWR
| O_CREAT
, 0600))) {
220 DEBUG(0, ("Unable to open idmap database\n"));
224 /* Create high water marks for group and user id */
226 if (tdb_fetch_int(idmap_tdb
, HWM_USER
) == -1) {
227 if (tdb_store_int(idmap_tdb
, HWM_USER
, server_state
.uid_low
) == -1) {
228 DEBUG(0, ("Unable to initialise user hwm in idmap database\n"));
233 if (tdb_fetch_int(idmap_tdb
, HWM_GROUP
) == -1) {
234 if (tdb_store_int(idmap_tdb
, HWM_GROUP
, server_state
.gid_low
) == -1) {
235 DEBUG(0, ("Unable to initialise group hwm in idmap database\n"));
243 BOOL
winbindd_idmap_close(void)
246 return (tdb_close(idmap_tdb
) == 0);
250 /* Dump status information to log file. Display different stuff based on
253 Debug Level Information Displayed
254 =================================================================
255 0 Percentage of [ug]id range allocated
256 0 High water marks (next allocated ids)
261 void winbindd_idmap_status(void)
263 int user_hwm
, group_hwm
;
265 DEBUG(0, ("winbindd idmap status:\n"));
267 /* Get current high water marks */
269 if ((user_hwm
= tdb_fetch_int(idmap_tdb
, HWM_USER
)) == -1) {
270 DEBUG(DUMP_INFO
, ("\tCould not get userid high water mark!\n"));
273 if ((group_hwm
= tdb_fetch_int(idmap_tdb
, HWM_GROUP
)) == -1) {
274 DEBUG(DUMP_INFO
, ("\tCould not get groupid high water mark!\n"));
277 /* Display next ids to allocate */
279 if (user_hwm
!= -1) {
280 DEBUG(DUMP_INFO
, ("\tNext userid to allocate is %d\n", user_hwm
));
283 if (group_hwm
!= -1) {
284 DEBUG(DUMP_INFO
, ("\tNext groupid to allocate is %d\n", group_hwm
));
287 /* Display percentage of id range already allocated. */
289 if (user_hwm
!= -1) {
290 int num_users
= user_hwm
- server_state
.uid_low
;
291 int total_users
= server_state
.uid_high
- server_state
.uid_low
;
293 DEBUG(DUMP_INFO
, ("\tUser id range is %d%% full (%d of %d)\n",
294 num_users
* 100 / total_users
, num_users
,
298 if (group_hwm
!= -1) {
299 int num_groups
= group_hwm
- server_state
.gid_low
;
300 int total_groups
= server_state
.gid_high
- server_state
.gid_low
;
302 DEBUG(DUMP_INFO
, ("\tGroup id range is %d%% full (%d of %d)\n",
303 num_groups
* 100 / total_groups
, num_groups
,
307 /* Display complete mapping of users and groups to rids */