summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbindd_cache.c
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2007-06-25 20:17:04 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:23:35 -0500
commit133472ac668033c8d8153709c7b7ddaa235aa453 (patch)
tree18cdd6930fe2e2182551cb8deea83b0f0d02bef4 /source3/nsswitch/winbindd_cache.c
parent386267447b9043eafb8497c0f1fca0f7eead821b (diff)
downloadsamba-133472ac668033c8d8153709c7b7ddaa235aa453.tar.gz
samba-133472ac668033c8d8153709c7b7ddaa235aa453.tar.bz2
samba-133472ac668033c8d8153709c7b7ddaa235aa453.zip
r23600: First step in abstracting the winbindd cache validation
code into a generic tdb validation code. In lib/util_tdb.c for a start. Michael (This used to be commit 527edfa0cbcb233218ebabc395666d1d7228ee37)
Diffstat (limited to 'source3/nsswitch/winbindd_cache.c')
-rw-r--r--source3/nsswitch/winbindd_cache.c244
1 files changed, 25 insertions, 219 deletions
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index 017a2ebfeb..122432d95b 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -2749,16 +2749,8 @@ BOOL get_global_winbindd_state_offline(void)
Validate functions for all possible cache tdb keys.
***********************************************************************/
-struct validation_status {
- BOOL tdb_error;
- BOOL bad_freelist;
- BOOL bad_entry;
- BOOL unknown_key;
- BOOL success;
-};
-
static struct cache_entry *create_centry_validate(const char *kstr, TDB_DATA data,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry;
@@ -2786,7 +2778,7 @@ static struct cache_entry *create_centry_validate(const char *kstr, TDB_DATA dat
}
static int validate_seqnum(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
if (dbuf.dsize != 8) {
DEBUG(0,("validate_seqnum: Corrupt cache for key %s (len %u != 8) ?\n",
@@ -2798,7 +2790,7 @@ static int validate_seqnum(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbu
}
static int validate_ns(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
if (!centry) {
@@ -2821,7 +2813,7 @@ static int validate_ns(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
}
static int validate_sn(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
if (!centry) {
@@ -2844,7 +2836,7 @@ static int validate_sn(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
}
static int validate_u(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
DOM_SID sid;
@@ -2871,7 +2863,7 @@ static int validate_u(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
}
static int validate_loc_pol(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
@@ -2893,7 +2885,7 @@ static int validate_loc_pol(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA db
}
static int validate_pwd_pol(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
@@ -2917,7 +2909,7 @@ static int validate_pwd_pol(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA db
}
static int validate_cred(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
@@ -2943,7 +2935,7 @@ static int validate_cred(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
}
static int validate_ul(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
int32 num_entries, i;
@@ -2974,7 +2966,7 @@ static int validate_ul(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
}
static int validate_gl(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
int32 num_entries, i;
@@ -3001,7 +2993,7 @@ static int validate_gl(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
}
static int validate_ug(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
int32 num_groups, i;
@@ -3027,7 +3019,7 @@ static int validate_ug(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
}
static int validate_ua(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
int32 num_aliases, i;
@@ -3052,7 +3044,7 @@ static int validate_ua(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
}
static int validate_gm(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
int32 num_names, i;
@@ -3080,7 +3072,7 @@ static int validate_gm(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
}
static int validate_dr(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
/* Can't say anything about this other than must be nonzero. */
if (dbuf.dsize == 0) {
@@ -3096,7 +3088,7 @@ static int validate_dr(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
}
static int validate_de(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
/* Can't say anything about this other than must be nonzero. */
if (dbuf.dsize == 0) {
@@ -3112,7 +3104,7 @@ static int validate_de(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
}
static int validate_trustdoms(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
int32 num_domains, i;
@@ -3141,7 +3133,7 @@ static int validate_trustdoms(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA
static int validate_trustdomcache(TALLOC_CTX *mem_ctx, const char *keystr,
TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
if (dbuf.dsize == 0) {
DEBUG(0, ("validate_trustdomcache: Corrupt cache for "
@@ -3157,7 +3149,7 @@ static int validate_trustdomcache(TALLOC_CTX *mem_ctx, const char *keystr,
}
static int validate_offline(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
if (dbuf.dsize != 4) {
DEBUG(0,("validate_offline: Corrupt cache for key %s (len %u != 4) ?\n",
@@ -3171,7 +3163,7 @@ static int validate_offline(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA db
}
static int validate_cache_version(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
- struct validation_status *state)
+ struct tdb_validation_status *state)
{
if (dbuf.dsize != 4) {
DEBUG(0, ("validate_cache_version: Corrupt cache for "
@@ -3193,7 +3185,7 @@ static int validate_cache_version(TALLOC_CTX *mem_ctx, const char *keystr, TDB_D
struct key_val_struct {
const char *keyname;
- int (*validate_data_fn)(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf, struct validation_status* state);
+ int (*validate_data_fn)(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf, struct tdb_validation_status* state);
} key_val[] = {
{"SEQNUM/", validate_seqnum},
{"NS/", validate_ns},
@@ -3224,7 +3216,7 @@ struct key_val_struct {
static int cache_traverse_validate_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
{
int i;
- struct validation_status *v_state = (struct validation_status *)state;
+ struct tdb_validation_status *v_state = (struct tdb_validation_status *)state;
/* Paranoia check. */
if (kbuf.dsize > 1024) {
@@ -3285,201 +3277,15 @@ static void validate_panic(const char *const why)
function) will restart us as we don't know if we crashed or not.
***********************************************************************/
-/*
- * internal validation function, executed by the child.
- */
-static int winbindd_validate_cache_child(const char *cache_path, int pfd)
-{
- int ret = -1;
- int tfd = -1;
- int num_entries = 0;
- TDB_CONTEXT *tdb = NULL;
- struct validation_status v_status;
-
- v_status.tdb_error = False;
- v_status.bad_freelist = False;
- v_status.bad_entry = False;
- v_status.unknown_key = False;
- v_status.success = True;
-
- tdb = tdb_open_log(cache_path,
- WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
- lp_winbind_offline_logon()
- ? TDB_DEFAULT
- : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST),
- O_RDWR|O_CREAT, 0600);
- if (!tdb) {
- v_status.tdb_error = True;
- v_status.success = False;
- goto out;
- }
-
- tfd = tdb_fd(tdb);
-
- /* Check the cache freelist is good. */
- if (tdb_validate_freelist(tdb, &num_entries) == -1) {
- DEBUG(0,("winbindd_validate_cache_child: bad freelist in cache %s\n",
- cache_path));
- v_status.bad_freelist = True;
- v_status.success = False;
- goto out;
- }
-
- DEBUG(10,("winbindd_validate_cache_child: cache %s freelist has %d entries\n",
- cache_path, num_entries));
-
- /* Now traverse the cache to validate it. */
- num_entries = tdb_traverse(tdb, cache_traverse_validate_fn, (void *)&v_status);
- if (num_entries == -1 || !(v_status.success)) {
- DEBUG(0,("winbindd_validate_cache_child: cache %s traverse failed\n",
- cache_path));
- if (!(v_status.success)) {
- if (v_status.bad_entry) {
- DEBUGADD(0, (" -> bad entry found\n"));
- }
- if (v_status.unknown_key) {
- DEBUGADD(0, (" -> unknown key encountered\n"));
- }
- }
- goto out;
- }
-
- DEBUG(10,("winbindd_validate_cache_child: cache %s is good "
- "with %d entries\n", cache_path, num_entries));
- ret = 0; /* Cache is good. */
-
-out:
- if (tdb) {
- if (ret == 0) {
- tdb_close(tdb);
- }
- else if (tfd != -1) {
- close(tfd);
- }
- }
-
- DEBUG(10, ("winbindd_validate_cache_child: writing status to pipe\n"));
- write (pfd, (const char *)&v_status, sizeof(v_status));
- close(pfd);
-
- return ret;
-}
-
int winbindd_validate_cache(void)
{
- pid_t child_pid = -1;
- int child_status = 0;
- int wait_pid = 0;
- int ret = -1;
- int pipe_fds[2];
- struct validation_status v_status;
- int bytes_read = 0;
- const char *cache_path = lock_path("winbindd_cache.tdb");
-
+ int ret;
+
DEBUG(10, ("winbindd_validate_cache: replacing panic function\n"));
smb_panic_fn = validate_panic;
- /* fork and let the child do the validation.
- * benefit: no need to twist signal handlers and panic functions.
- * just let the child panic. we catch the signal.
- * communicate the extended status struct over a pipe. */
-
- if (pipe(pipe_fds) != 0) {
- DEBUG(0, ("winbindd_validate_cache: unable to create pipe, "
- "error %s", strerror(errno)));
- smb_panic("winbind_validate_cache: unable to create pipe.");
- }
-
- DEBUG(10, ("winbindd_validate_cache: forking to let child do validation.\n"));
- child_pid = sys_fork();
- if (child_pid == 0) {
- DEBUG(10, ("winbindd_validate_cache (validation child): created\n"));
- close(pipe_fds[0]); /* close reading fd */
- DEBUG(10, ("winbindd_validate_cache (validation child): "
- "calling winbindd_validate_cache_child\n"));
- exit(winbindd_validate_cache_child(cache_path, pipe_fds[1]));
- }
- else if (child_pid < 0) {
- smb_panic("winbindd_validate_cache: fork for validation failed.");
- }
-
- /* parent */
-
- DEBUG(10, ("winbindd_validate_cache: fork succeeded, child PID = %d\n",
- child_pid));
- close(pipe_fds[1]); /* close writing fd */
-
- v_status.success = True;
- v_status.bad_entry = False;
- v_status.unknown_key = False;
-
- DEBUG(10, ("winbindd_validate_cache: reading from pipe.\n"));
- bytes_read = read(pipe_fds[0], (void *)&v_status, sizeof(v_status));
- close(pipe_fds[0]);
-
- if (bytes_read != sizeof(v_status)) {
- DEBUG(10, ("winbindd_validate_cache: read %d bytes from pipe "
- "but expected %d", bytes_read, (int)sizeof(v_status)));
- DEBUGADD(10, (" -> assuming child crashed\n"));
- v_status.success = False;
- }
- else {
- DEBUG(10, ("winbindd_validate_cache: read status from child\n"));
- DEBUGADD(10, (" * tdb error: %s\n", v_status.tdb_error ? "yes" : "no"));
- DEBUGADD(10, (" * bad freelist: %s\n", v_status.bad_freelist ? "yes" : "no"));
- DEBUGADD(10, (" * bad entry: %s\n", v_status.bad_entry ? "yes" : "no"));
- DEBUGADD(10, (" * unknown key: %s\n", v_status.unknown_key ? "yes" : "no"));
- DEBUGADD(10, (" => overall success: %s\n", v_status.success ? "yes" : "no"));
- }
-
- if (!v_status.success) {
- DEBUG(10, ("winbindd_validate_cache: validation not successful.\n"));
- DEBUGADD(10, ("removing tdb %s.\n", cache_path));
- unlink(cache_path);
- }
-
- DEBUG(10, ("winbindd_validate_cache: waiting for child to finish...\n"));
- while ((wait_pid = sys_waitpid(child_pid, &child_status, 0)) < 0) {
- if (errno == EINTR) {
- DEBUG(10, ("winbindd_validate_cache: got signal during "
- "waitpid, retrying\n"));
- errno = 0;
- continue;
- }
- DEBUG(0, ("winbindd_validate_cache: waitpid failed with "
- "errno %s\n", strerror(errno)));
- smb_panic("winbindd_validate_cache: waitpid failed.");
- }
- if (wait_pid != child_pid) {
- DEBUG(0, ("winbindd_validate_cache: waitpid returned pid %d, "
- "but %d was expexted\n", wait_pid, child_pid));
- smb_panic("winbindd_validate_cache: waitpid returned "
- "unexpected PID.");
- }
-
-
- DEBUG(10, ("winbindd_validate_cache: validating child returned.\n"));
- if (WIFEXITED(child_status)) {
- DEBUG(10, ("winbindd_validate_cache: child exited, code %d.\n",
- WEXITSTATUS(child_status)));
- ret = WEXITSTATUS(child_status);
- }
- if (WIFSIGNALED(child_status)) {
- DEBUG(10, ("winbindd_validate_cache: child terminated "
- "by signal %d\n", WTERMSIG(child_status)));
-#ifdef WCOREDUMP
- if (WCOREDUMP(child_status)) {
- DEBUGADD(10, ("core dumped\n"));
- }
-#endif
- ret = WTERMSIG(child_status);
- }
- if (WIFSTOPPED(child_status)) {
- DEBUG(10, ("winbindd_validate_cache: child was stopped "
- "by signal %d\n",
- WSTOPSIG(child_status)));
- ret = WSTOPSIG(child_status);
- }
+ ret = tdb_validate(lock_path("winbindd_cache.tdb"),
+ cache_traverse_validate_fn);
DEBUG(10, ("winbindd_validate_cache: restoring panic function\n"));
smb_panic_fn = smb_panic;