summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2002-04-04 03:03:39 +0000
committerJeremy Allison <jra@samba.org>2002-04-04 03:03:39 +0000
commit464c1201978a2cd5abed8ea0d7bcb9486b1c92d8 (patch)
treeeb67239c0c47ace3535d59cbf1dbd6c2a6494a10
parentf21ccff91fe9dd37a57c6505fc19b7fc2c103a59 (diff)
downloadsamba-464c1201978a2cd5abed8ea0d7bcb9486b1c92d8.tar.gz
samba-464c1201978a2cd5abed8ea0d7bcb9486b1c92d8.tar.bz2
samba-464c1201978a2cd5abed8ea0d7bcb9486b1c92d8.zip
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)
-rw-r--r--source3/nsswitch/winbindd.c4
-rw-r--r--source3/nsswitch/winbindd_cache.c31
-rw-r--r--source3/nsswitch/winbindd_idmap.c210
-rw-r--r--source3/nsswitch/winbindd_proto.h1
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 */