From 464c1201978a2cd5abed8ea0d7bcb9486b1c92d8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 Apr 2002 03:03:39 +0000 Subject: Fix up conversion code from old winbindd versions (some testing needed). Added time based cache size check (#ifdef'ed out by default, just didn't want to lose the code). Jeremy. (This used to be commit b2350ed36c42827c417ea4a3dd0668a4a631a090) --- source3/nsswitch/winbindd.c | 4 + source3/nsswitch/winbindd_cache.c | 31 ++++++ source3/nsswitch/winbindd_idmap.c | 210 ++++++++++++++++++++++++++------------ source3/nsswitch/winbindd_proto.h | 1 + 4 files changed, 179 insertions(+), 67 deletions(-) diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 7e1372614b..e9ee2a7693 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -631,6 +631,10 @@ static void process_loop(int accept_sock) } } +#if 0 + winbindd_check_cache_size(time(NULL)); +#endif + /* Check signal handling things */ if (do_sigterm) diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index 230d2b88b8..9bd95fdd86 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -34,6 +34,8 @@ struct cache_entry { uint32 len, ofs; }; +#define WINBINDD_MAX_CACHE_SIZE (50*1024*1024) + static struct winbind_cache *wcache; /* flush the cache */ @@ -56,6 +58,35 @@ void wcache_flush_cache(void) } } +void winbindd_check_cache_size(time_t t) +{ + static time_t last_check_time; + struct stat st; + + if (last_check_time == (time_t)0) + last_check_time = t; + + if (t - last_check_time < 60 && t - last_check_time > 0) + return; + + if (wcache == NULL || wcache->tdb == NULL) { + DEBUG(0, ("Unable to check size of tdb cache - cache not open !\n")); + return; + } + + if (fstat(wcache->tdb->fd, &st) == -1) { + DEBUG(0, ("Unable to check size of tdb cache %s!\n", strerror(errno) )); + return; + } + + if (st.st_size > WINBINDD_MAX_CACHE_SIZE) { + DEBUG(10,("flushing cache due to size (%lu) > (%lu)\n", + (unsigned long)st.st_size, + (unsigned long)WINBINDD_MAX_CACHE_SIZE)); + wcache_flush_cache(); + } +} + /* get the winbind_cache structure */ static struct winbind_cache *get_cache(struct winbindd_domain *domain) { diff --git a/source3/nsswitch/winbindd_idmap.c b/source3/nsswitch/winbindd_idmap.c index 897d93b0f0..bae61449ee 100644 --- a/source3/nsswitch/winbindd_idmap.c +++ b/source3/nsswitch/winbindd_idmap.c @@ -244,24 +244,28 @@ BOOL winbindd_idmap_get_rid_from_gid(gid_t gid, uint32 *group_rid, static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *ignored) { struct winbindd_domain *domain; - char *p, *dom_name; + char *p; DOM_SID sid; uint32 rid; fstring keystr; + fstring dom_name; TDB_DATA key2; p = strchr(key.dptr, '/'); - if (!p) return 0; + if (!p) + return 0; - *p++ = 0; - dom_name = key.dptr; + *p = 0; + fstrcpy(dom_name, key.dptr); + *p++ = '/'; domain = find_domain_from_name(dom_name); if (!domain) { - /* what do we do about this?? */ + /* We must delete the old record. */ DEBUG(0,("winbindd: convert_fn : Unable to find domain %s\n", dom_name )); - DEBUG(0,("winbindd: convert_fn : conversion failed - idmap corrupt ?\n")); - return -1; + DEBUG(0,("winbindd: convert_fn : deleting record %s\n", key.dptr )); + tdb_delete(idmap_tdb, key); + return 0; } rid = atoi(p); @@ -292,14 +296,84 @@ static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *ignor return 0; } -/* convert the idmap database from an older version */ -static BOOL idmap_convert(void) +#if 0 +/***************************************************************************** + Make a backup copy of the old idmap just to be safe.... JRA. +*****************************************************************************/ + +static BOOL backup_old_idmap(const char *idmap_name) +{ + pstring new_name; + int outfd = -1; + SMB_OFF_T size; + struct stat st; + + pstrcpy(new_name, idmap_name); + pstrcat(new_name, ".bak"); + + DEBUG(10,("backup_old_idmap: backing up %s to %s before upgrade.\n", + idmap_name, new_name )); + + if (tdb_lockall(idmap_tdb) == -1) { + DEBUG(10,("backup_old_idmap: failed to lock %s. Error %s\n", + idmap_name, tdb_errorstr(idmap_tdb) )); + return False; + } + if ((outfd = open(new_name, O_CREAT|O_EXCL|O_RDWR, 0600)) == -1) { + DEBUG(10,("backup_old_idmap: failed to open %s. Error %s\n", + new_name, strerror(errno) )); + goto fail; + } + + if (fstat(idmap_tdb->fd, &st) == -1) { + DEBUG(10,("backup_old_idmap: failed to fstat %s. Error %s\n", + idmap_name, strerror(errno) )); + goto fail; + } + + size = (SMB_OFF_T)st.st_size; + + if (transfer_file(idmap_tdb->fd, outfd, size) != size ) { + DEBUG(10,("backup_old_idmap: failed to copy %s. Error %s\n", + idmap_name, strerror(errno) )); + goto fail; + } + + if (close(outfd) == -1) { + DEBUG(10,("backup_old_idmap: failed to close %s. Error %s\n", + idmap_name, strerror(errno) )); + outfd = -1; + goto fail; + } + tdb_unlockall(idmap_tdb); + return True; + +fail: + + if (outfd != -1) + close(outfd); + tdb_unlockall(idmap_tdb); + return False; +} +#endif + +/***************************************************************************** + Convert the idmap database from an older version. +*****************************************************************************/ + +static BOOL idmap_convert(const char *idmap_name) { int32 vers = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION"); if (vers == IDMAP_VERSION) return True; +#if 0 + /* Make a backup copy before doing anything else.... */ + if (!backup_old_idmap(idmap_name)) + return False; +#endif + if (IREV(vers) == IDMAP_VERSION) { /* Arrggghh ! Bytereversed - make order independent ! */ int32 wm; @@ -338,41 +412,43 @@ static BOOL idmap_convert(void) return True; } - -/* Initialise idmap database */ +/***************************************************************************** + Initialise idmap database. +*****************************************************************************/ BOOL winbindd_idmap_init(void) { - /* Open tdb cache */ + /* Open tdb cache */ - if (!(idmap_tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0, - TDB_DEFAULT, O_RDWR | O_CREAT, 0600))) { - DEBUG(0, ("Unable to open idmap database\n")); - return False; - } + if (!(idmap_tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0, + TDB_DEFAULT, O_RDWR | O_CREAT, 0600))) { + DEBUG(0, ("winbindd_idmap_init: Unable to open idmap database\n")); + return False; + } - /* possibly convert from an earlier version */ - if (!idmap_convert()) { - return False; - } + /* possibly convert from an earlier version */ + if (!idmap_convert(lock_path("winbindd_idmap.tdb"))) { + DEBUG(0, ("winbindd_idmap_init: Unable to open idmap database\n")); + return False; + } - /* Create high water marks for group and user id */ + /* Create high water marks for group and user id */ - if (tdb_fetch_int32(idmap_tdb, HWM_USER) == -1) { - if (tdb_store_int32(idmap_tdb, HWM_USER, server_state.uid_low) == -1) { - DEBUG(0, ("winbindd_idmap_init: Unable to initialise user hwm in idmap database\n")); - return False; - } - } + if (tdb_fetch_int32(idmap_tdb, HWM_USER) == -1) { + if (tdb_store_int32(idmap_tdb, HWM_USER, server_state.uid_low) == -1) { + DEBUG(0, ("winbindd_idmap_init: Unable to initialise user hwm in idmap database\n")); + return False; + } + } - if (tdb_fetch_int32(idmap_tdb, HWM_GROUP) == -1) { - if (tdb_store_int32(idmap_tdb, HWM_GROUP, server_state.gid_low) == -1) { - DEBUG(0, ("winbindd_idmap_init: Unable to initialise group hwm in idmap database\n")); - return False; - } - } + if (tdb_fetch_int32(idmap_tdb, HWM_GROUP) == -1) { + if (tdb_store_int32(idmap_tdb, HWM_GROUP, server_state.gid_low) == -1) { + DEBUG(0, ("winbindd_idmap_init: Unable to initialise group hwm in idmap database\n")); + return False; + } + } - return True; + return True; } BOOL winbindd_idmap_close(void) @@ -395,49 +471,49 @@ BOOL winbindd_idmap_close(void) void winbindd_idmap_status(void) { - int user_hwm, group_hwm; + int user_hwm, group_hwm; - DEBUG(0, ("winbindd idmap status:\n")); + DEBUG(0, ("winbindd idmap status:\n")); - /* Get current high water marks */ + /* Get current high water marks */ - if ((user_hwm = tdb_fetch_int32(idmap_tdb, HWM_USER)) == -1) { - DEBUG(DUMP_INFO, ("\tCould not get userid high water mark!\n")); - } + if ((user_hwm = tdb_fetch_int32(idmap_tdb, HWM_USER)) == -1) { + DEBUG(DUMP_INFO, ("\tCould not get userid high water mark!\n")); + } - if ((group_hwm = tdb_fetch_int32(idmap_tdb, HWM_GROUP)) == -1) { - DEBUG(DUMP_INFO, ("\tCould not get groupid high water mark!\n")); - } + if ((group_hwm = tdb_fetch_int32(idmap_tdb, HWM_GROUP)) == -1) { + DEBUG(DUMP_INFO, ("\tCould not get groupid high water mark!\n")); + } - /* Display next ids to allocate */ + /* Display next ids to allocate */ - if (user_hwm != -1) { - DEBUG(DUMP_INFO, ("\tNext userid to allocate is %d\n", user_hwm)); - } + if (user_hwm != -1) { + DEBUG(DUMP_INFO, ("\tNext userid to allocate is %d\n", user_hwm)); + } - if (group_hwm != -1) { - DEBUG(DUMP_INFO, ("\tNext groupid to allocate is %d\n", group_hwm)); - } + if (group_hwm != -1) { + DEBUG(DUMP_INFO, ("\tNext groupid to allocate is %d\n", group_hwm)); + } - /* Display percentage of id range already allocated. */ + /* Display percentage of id range already allocated. */ - if (user_hwm != -1) { - int num_users = user_hwm - server_state.uid_low; - int total_users = server_state.uid_high - server_state.uid_low; + if (user_hwm != -1) { + int num_users = user_hwm - server_state.uid_low; + int total_users = server_state.uid_high - server_state.uid_low; - DEBUG(DUMP_INFO, ("\tUser id range is %d%% full (%d of %d)\n", - num_users * 100 / total_users, num_users, - total_users)); - } + DEBUG(DUMP_INFO, ("\tUser id range is %d%% full (%d of %d)\n", + num_users * 100 / total_users, num_users, + total_users)); + } - if (group_hwm != -1) { - int num_groups = group_hwm - server_state.gid_low; - int total_groups = server_state.gid_high - server_state.gid_low; + if (group_hwm != -1) { + int num_groups = group_hwm - server_state.gid_low; + int total_groups = server_state.gid_high - server_state.gid_low; - DEBUG(DUMP_INFO, ("\tGroup id range is %d%% full (%d of %d)\n", - num_groups * 100 / total_groups, num_groups, - total_groups)); - } + DEBUG(DUMP_INFO, ("\tGroup id range is %d%% full (%d of %d)\n", + num_groups * 100 / total_groups, num_groups, + total_groups)); + } - /* Display complete mapping of users and groups to rids */ + /* Display complete mapping of users and groups to rids */ } diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h index f12c56e8b1..f3830cd63c 100644 --- a/source3/nsswitch/winbindd_proto.h +++ b/source3/nsswitch/winbindd_proto.h @@ -23,6 +23,7 @@ ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res, /* The following definitions come from nsswitch/winbindd_cache.c */ void wcache_flush_cache(void); +void winbindd_check_cache_size(time_t t); struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status); /* The following definitions come from nsswitch/winbindd_cm.c */ -- cgit