void netsamlogon_clear_cached_user(const struct dom_sid *user_sid) { char keystr[DOM_SID_STR_BUFLEN]; if (!netsamlogon_cache_init()) { DEBUG(0,("netsamlogon_clear_cached_user: cannot open " "%s for write!\n", NETSAMLOGON_TDB)); return; } /* Prepare key as DOMAIN-SID/USER-RID string */ dom_sid_string_buf(user_sid, keystr, sizeof(keystr)); DEBUG(10,("netsamlogon_clear_cached_user: SID [%s]\n", keystr)); tdb_delete_bystring(netsamlogon_tdb, keystr); }
bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3) { uint8_t dummy = 0; TDB_DATA data = { .dptr = &dummy, .dsize = sizeof(dummy) }; char keystr[DOM_SID_STR_BUFLEN]; bool result = false; struct dom_sid user_sid; TALLOC_CTX *tmp_ctx = talloc_stackframe(); DATA_BLOB blob; enum ndr_err_code ndr_err; struct netsamlogoncache_entry r; int ret; if (!info3) { return false; } if (!netsamlogon_cache_init()) { DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB)); return false; } /* * First write a record with just the domain sid for * netsamlogon_cache_domain_known. Use TDB_INSERT to avoid * overwriting potentially other data. We're just interested * in the existence of that record. */ dom_sid_string_buf(info3->base.domain_sid, keystr, sizeof(keystr)); ret = tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_INSERT); if ((ret == -1) && (tdb_error(netsamlogon_tdb) != TDB_ERR_EXISTS)) { DBG_WARNING("Could not store domain marker for %s: %s\n", keystr, tdb_errorstr(netsamlogon_tdb)); TALLOC_FREE(tmp_ctx); return false; } sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid); /* Prepare key as DOMAIN-SID/USER-RID string */ dom_sid_string_buf(&user_sid, keystr, sizeof(keystr)); DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr)); /* Prepare data */ if (info3->base.full_name.string == NULL) { struct netr_SamInfo3 *cached_info3; const char *full_name = NULL; cached_info3 = netsamlogon_cache_get(tmp_ctx, &user_sid); if (cached_info3 != NULL) { full_name = cached_info3->base.full_name.string; } if (full_name != NULL) { info3->base.full_name.string = talloc_strdup(info3, full_name); } } /* only Samba fills in the username, not sure why NT doesn't */ /* so we fill it in since winbindd_getpwnam() makes use of it */ if (!info3->base.account_name.string) { info3->base.account_name.string = talloc_strdup(info3, username); } r.timestamp = time(NULL); r.info3 = *info3; if (DEBUGLEVEL >= 10) { NDR_PRINT_DEBUG(netsamlogoncache_entry, &r); } ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, &r, (ndr_push_flags_fn_t)ndr_push_netsamlogoncache_entry); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0,("netsamlogon_cache_store: failed to push entry to cache\n")); TALLOC_FREE(tmp_ctx); return false; } data.dsize = blob.length; data.dptr = blob.data; if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) == 0) { result = true; } TALLOC_FREE(tmp_ctx); return result; } /*********************************************************************** Retrieves a netr_SamInfo3 structure from a tdb. Caller must free the user_info struct (talloced memory) ***********************************************************************/ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const struct dom_sid *user_sid) { struct netr_SamInfo3 *info3 = NULL; TDB_DATA data; char keystr[DOM_SID_STR_BUFLEN]; enum ndr_err_code ndr_err; DATA_BLOB blob; struct netsamlogoncache_entry r; if (!netsamlogon_cache_init()) { DEBUG(0,("netsamlogon_cache_get: cannot open %s for write!\n", NETSAMLOGON_TDB)); return NULL; } /* Prepare key as DOMAIN-SID/USER-RID string */ dom_sid_string_buf(user_sid, keystr, sizeof(keystr)); DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr)); data = tdb_fetch_bystring( netsamlogon_tdb, keystr ); if (!data.dptr) { return NULL; } info3 = talloc_zero(mem_ctx, struct netr_SamInfo3); if (!info3) { goto done; } blob = data_blob_const(data.dptr, data.dsize); ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, (ndr_pull_flags_fn_t)ndr_pull_netsamlogoncache_entry); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0,("netsamlogon_cache_get: failed to pull entry from cache\n")); tdb_delete_bystring(netsamlogon_tdb, keystr); TALLOC_FREE(info3); goto done; } if (DEBUGLEVEL >= 10) { NDR_PRINT_DEBUG(netsamlogoncache_entry, &r); } info3 = (struct netr_SamInfo3 *)talloc_memdup(mem_ctx, &r.info3, sizeof(r.info3)); done: SAFE_FREE(data.dptr); return info3; } bool netsamlogon_cache_have(const struct dom_sid *sid) { char keystr[DOM_SID_STR_BUFLEN]; bool ok; if (!netsamlogon_cache_init()) { DBG_WARNING("Cannot open %s\n", NETSAMLOGON_TDB); return false; } dom_sid_string_buf(sid, keystr, sizeof(keystr)); ok = tdb_exists(netsamlogon_tdb, string_term_tdb_data(keystr)); return ok; }
int main(int argc, char **argv) { pstring logfile; static BOOL interactive = False; static BOOL Fork = True; static BOOL log_stdout = False; struct poptOption long_options[] = { POPT_AUTOHELP { "stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" }, { "foreground", 'F', POPT_ARG_VAL, &Fork, False, "Daemon in foreground mode" }, { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" }, { "single-daemon", 'Y', POPT_ARG_VAL, &opt_dual_daemon, False, "Single daemon mode" }, { "no-caching", 'n', POPT_ARG_VAL, &opt_nocache, True, "Disable caching" }, POPT_COMMON_SAMBA POPT_TABLEEND }; poptContext pc; int opt; /* glibc (?) likes to print "User defined signal 1" and exit if a SIGUSR[12] is received before a handler is installed */ CatchSignal(SIGUSR1, SIG_IGN); CatchSignal(SIGUSR2, SIG_IGN); fault_setup((void (*)(void *))fault_quit ); /* Initialise for running in non-root mode */ sec_init(); set_remote_machine_name("winbindd", False); /* Set environment variable so we don't recursively call ourselves. This may also be useful interactively. */ setenv(WINBINDD_DONT_ENV, "1", 1); /* Initialise samba/rpc client stuff */ pc = poptGetContext("winbindd", argc, (const char **)argv, long_options, POPT_CONTEXT_KEEP_FIRST); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { /* Don't become a daemon */ case 'i': interactive = True; log_stdout = True; Fork = False; break; } } if (log_stdout && Fork) { printf("Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n"); poptPrintUsage(pc, stderr, 0); exit(1); } pstr_sprintf(logfile, "%s/log.winbindd", dyn_LOGFILEBASE); lp_set_logfile(logfile); setup_logging("winbindd", log_stdout); reopen_logs(); DEBUG(1, ("winbindd version %s started.\n", SAMBA_VERSION_STRING) ); DEBUGADD( 1, ( "Copyright The Samba Team 2000-2004\n" ) ); if (!reload_services_file()) { DEBUG(0, ("error opening config file\n")); exit(1); } /* Setup names. */ if (!init_names()) exit(1); load_interfaces(); if (!secrets_init()) { DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n")); return False; } /* Enable netbios namecache */ namecache_enable(); /* Check winbindd parameters are valid */ ZERO_STRUCT(server_state); /* Winbind daemon initialisation */ if ( (!winbindd_param_init()) || (!winbindd_upgrade_idmap()) || (!idmap_init(lp_idmap_backend())) ) { DEBUG(1, ("Could not init idmap -- netlogon proxy only\n")); idmap_proxyonly(); } generate_wellknown_sids(); /* Unblock all signals we are interested in as they may have been blocked by the parent process. */ BlockSignals(False, SIGINT); BlockSignals(False, SIGQUIT); BlockSignals(False, SIGTERM); BlockSignals(False, SIGUSR1); BlockSignals(False, SIGUSR2); BlockSignals(False, SIGHUP); BlockSignals(False, SIGCHLD); /* Setup signal handlers */ CatchSignal(SIGINT, termination_handler); /* Exit on these sigs */ CatchSignal(SIGQUIT, termination_handler); CatchSignal(SIGTERM, termination_handler); CatchSignal(SIGCHLD, sigchld_handler); CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */ CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */ CatchSignal(SIGHUP, sighup_handler); if (!interactive) become_daemon(Fork); pidfile_create("winbindd"); #if HAVE_SETPGID /* * If we're interactive we want to set our own process group for * signal management. */ if (interactive) setpgid( (pid_t)0, (pid_t)0); #endif if (opt_dual_daemon) { do_dual_daemon(); } /* Initialise messaging system */ if (!message_init()) { DEBUG(0, ("unable to initialise messaging system\n")); exit(1); } /* React on 'smbcontrol winbindd reload-config' in the same way as to SIGHUP signal */ message_register(MSG_SMB_CONF_UPDATED, msg_reload_services); message_register(MSG_SHUTDOWN, msg_shutdown); poptFreeContext(pc); netsamlogon_cache_init(); /* Non-critical */ init_domain_list(); /* Loop waiting for requests */ process_loop(); trustdom_cache_shutdown(); return 0; }