/*
- Unix SMB/Netbios implementation.
- Version 3.0
+ Unix SMB/CIFS implementation.
Winbind daemon for ntdom nss module
Copyright (C) by Tim Potter 2000, 2001
+ Copyright (C) Andrew Tridgell 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
struct winbindd_cli_state *client_list;
static int num_clients;
-BOOL opt_nocache;
+BOOL opt_nocache = False;
+BOOL opt_dual_daemon = False;
/* Reload configuration */
static void termination_handler(int signum)
{
do_sigterm = True;
+ sys_select_signal();
}
static BOOL do_sigusr2;
static void sigusr2_handler(int signum)
{
do_sigusr2 = True;
+ sys_select_signal();
}
static BOOL do_sighup;
static void sighup_handler(int signum)
{
do_sighup = True;
+ sys_select_signal();
}
/* Create winbindd socket */
{ WINBINDD_SETGRENT, winbindd_setgrent, "SETGRENT" },
{ WINBINDD_ENDGRENT, winbindd_endgrent, "ENDGRENT" },
{ WINBINDD_GETGRENT, winbindd_getgrent, "GETGRENT" },
+ { WINBINDD_GETGRLST, winbindd_getgrent, "GETGRLST" },
/* PAM auth functions */
{ WINBINDD_LIST_USERS, winbindd_list_users, "LIST_USERS" },
{ WINBINDD_LIST_GROUPS, winbindd_list_groups, "LIST_GROUPS" },
{ WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains, "LIST_TRUSTDOM" },
+ { WINBINDD_SHOW_SEQUENCE, winbindd_show_sequence, "SHOW_SEQUENCE" },
/* SID related functions */
{ WINBINDD_PING, winbindd_ping, "PING" },
{ WINBINDD_INFO, winbindd_info, "INFO" },
{ WINBINDD_INTERFACE_VERSION, winbindd_interface_version, "INTERFACE_VERSION" },
+ { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
+
+ /* WINS functions */
+
+ { WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },
+ { WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" },
/* End of list */
}
}
+
/* Process a complete received packet from a client */
-static void process_packet(struct winbindd_cli_state *state)
+void winbind_process_packet(struct winbindd_cli_state *state)
{
/* Process request */
state->read_buf_len = 0;
state->write_buf_len = sizeof(struct winbindd_response);
+
+ /* we might need to send it to the dual daemon */
+ if (opt_dual_daemon) {
+ dual_send_request(state);
+ }
}
/* Read some data from a client connection */
-static void client_read(struct winbindd_cli_state *state)
+void winbind_client_read(struct winbindd_cli_state *state)
{
int n;
int maxfd = accept_sock, selret;
struct timeval timeout;
+ /* Handle messages */
+
+ message_dispatch();
+
/* Free up temporary memory */
lp_talloc_free();
+ main_loop_talloc_free();
/* Initialise fd lists for select() */
timeout.tv_sec = WINBINDD_ESTABLISH_LOOP;
timeout.tv_usec = 0;
+ if (opt_dual_daemon) {
+ maxfd = dual_select_setup(&w_fds, maxfd);
+ }
+
/* Set up client readers and writers */
state = client_list;
/* Call select */
- selret = select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
+ selret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
if (selret == 0)
continue;
if (selret > 0) {
+ if (opt_dual_daemon) {
+ dual_select(&w_fds);
+ }
+
if (FD_ISSET(accept_sock, &r_fds))
new_connection(accept_sock);
/* Read data */
- client_read(state);
+ winbind_client_read(state);
/*
* If we have the start of a
if (state->read_buf_len ==
sizeof(state->request)) {
- process_packet(state);
+ winbind_process_packet(state);
}
}
}
}
+#if 0
+ winbindd_check_cache_size(time(NULL));
+#endif
+
/* Check signal handling things */
if (do_sigterm)
}
}
+
+/*
+ these are split out from the main winbindd for use by the background daemon
+ */
+int winbind_setup_common(void)
+{
+ load_interfaces();
+
+ if (!secrets_init()) {
+
+ DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
+ return 1;
+
+ }
+
+ /* Get list of domains we look up requests for. This includes the
+ domain which we are a member of as well as any trusted
+ domains. */
+
+ init_domain_list();
+
+ ZERO_STRUCT(server_state);
+
+ /* Winbind daemon initialisation */
+
+ if (!winbindd_param_init())
+ return 1;
+
+ if (!winbindd_idmap_init())
+ return 1;
+
+ /* 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);
+
+ /* Setup signal handlers */
+
+ CatchSignal(SIGINT, termination_handler); /* Exit on these sigs */
+ CatchSignal(SIGQUIT, termination_handler);
+ CatchSignal(SIGTERM, termination_handler);
+
+ CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
+
+ CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */
+ CatchSignal(SIGHUP, sighup_handler);
+
+ return 0;
+}
+
+
/* Main function */
struct winbindd_state server_state; /* Server state information */
-int main(int argc, char **argv)
+
+static void usage(void)
+{
+ printf("Usage: winbindd [options]\n");
+ printf("\t-i interactive mode\n");
+ printf("\t-B dual daemon mode\n");
+ printf("\t-n disable cacheing\n");
+ printf("\t-d level set debug level\n");
+ printf("\t-s configfile choose smb.conf location\n");
+ printf("\t-h show this help message\n");
+}
+
+ int main(int argc, char **argv)
{
+ extern BOOL AllowDebugChange;
extern pstring global_myname;
extern fstring global_myworkgroup;
extern BOOL append_log;
pstring logfile;
int accept_sock;
BOOL interactive = False;
- int opt, new_debuglevel = -1;
+ int opt;
/* glibc (?) likes to print "User defined signal 1" and exit if a
- SIGUSR2 is received before a handler is installed */
+ SIGUSR[12] is received before a handler is installed */
+ CatchSignal(SIGUSR1, SIG_IGN);
CatchSignal(SIGUSR2, SIG_IGN);
fault_setup((void (*)(void *))fault_quit );
/* Initialise samba/rpc client stuff */
- while ((opt = getopt(argc, argv, "id:s:n")) != EOF) {
+ while ((opt = getopt(argc, argv, "id:s:nhB")) != EOF) {
switch (opt) {
/* Don't become a daemon */
interactive = True;
break;
+ /* dual daemon system */
+ case 'B':
+ opt_dual_daemon = True;
+ break;
+
/* disable cacheing */
case 'n':
opt_nocache = True;
/* Run with specified debug level */
case 'd':
- new_debuglevel = atoi(optarg);
+ DEBUGLEVEL = atoi(optarg);
+ AllowDebugChange = False;
break;
/* Load a different smb.conf file */
pstrcpy(dyn_CONFIGFILE,optarg);
break;
+ case 'h':
+ usage();
+ exit(0);
+
default:
printf("Unknown option %c\n", (char)opt);
exit(1);
}
/* Setup names. */
+
if (!*global_myname) {
char *p;
fstrcpy(global_myworkgroup, lp_workgroup());
- if (new_debuglevel != -1)
- DEBUGLEVEL = new_debuglevel;
-
- if (!interactive)
+ if (!interactive) {
become_daemon();
+ pidfile_create("winbindd");
+ }
#if HAVE_SETPGID
/*
setpgid( (pid_t)0, (pid_t)0);
#endif
- load_interfaces();
-
- secrets_init();
-
- /* Get list of domains we look up requests for. This includes the
- domain which we are a member of as well as any trusted
- domains. */
-
- init_domain_list();
-
- ZERO_STRUCT(server_state);
-
- /* Winbind daemon initialisation */
-
- if (!winbindd_param_init())
- return 1;
+ if (opt_dual_daemon) {
+ do_dual_daemon();
+ }
- if (!winbindd_idmap_init())
+ if (winbind_setup_common() != 0) {
return 1;
+ }
- /* 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, SIGUSR2);
- BlockSignals(False, SIGHUP);
-
- /* Setup signal handlers */
-
- CatchSignal(SIGINT, termination_handler); /* Exit on these sigs */
- CatchSignal(SIGQUIT, termination_handler);
- CatchSignal(SIGTERM, termination_handler);
+ /* Initialise messaging system */
- CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
- CatchSignal(SIGUSR1, SIG_IGN); /* Samba messages */
+ if (!message_init()) {
+ DEBUG(0, ("unable to initialise messaging system\n"));
+ exit(1);
+ }
- CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */
- CatchSignal(SIGHUP, sighup_handler);
+ register_msg_pool_usage();
/* Create UNIX domain socket */