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(int *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, int *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) {
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));
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(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 /* Dump status information to log file. Display different stuff based on
246 Debug Level Information Displayed
247 =================================================================
248 0 Percentage of [ug]id range allocated
249 0 High water marks (next allocated ids)
254 void winbindd_idmap_dump_status(void)
256 int user_hwm, group_hwm;
258 DEBUG(0, ("Status for winbindd idmap:\n"));
260 /* Get current high water marks */
262 if ((user_hwm = tdb_fetch_int(idmap_tdb, HWM_USER)) == -1) {
263 DEBUG(DUMP_INFO, ("\tCould not get userid high water mark!\n"));
266 if ((group_hwm = tdb_fetch_int(idmap_tdb, HWM_GROUP)) == -1) {
267 DEBUG(DUMP_INFO, ("\tCould not get groupid high water mark!\n"));
270 /* Display next ids to allocate */
272 if (user_hwm != -1) {
273 DEBUG(DUMP_INFO, ("\tNext userid to allocate is %d\n", user_hwm));
276 if (group_hwm != -1) {
277 DEBUG(DUMP_INFO, ("\tNext groupid to allocate is %d\n", group_hwm));
280 /* Display percentage of id range already allocated. */
282 if (user_hwm != -1) {
283 int num_users = user_hwm - server_state.uid_low;
284 int total_users = server_state.uid_high - server_state.uid_low;
286 DEBUG(DUMP_INFO, ("\tUser id range is %d%% full (%d of %d)\n",
287 num_users * 100 / total_users, num_users,
291 if (group_hwm != -1) {
292 int num_groups = group_hwm - server_state.gid_low;
293 int total_groups = server_state.gid_high - server_state.gid_low;
295 DEBUG(DUMP_INFO, ("\tGroup id range is %d%% full (%d of %d)\n",
296 num_groups * 100 / total_groups, num_groups,
300 /* Display complete mapping of users and groups to rids */