Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}