X-Git-Url: http://git.samba.org/samba.git/?p=nivanova%2Fsamba-autobuild%2F.git;a=blobdiff_plain;f=source3%2Fnsswitch%2Fwinbindd.c;h=358d9add3a388c10f3de544bcbfe8f3a8e946c2d;hp=713cef312f1fa4d5198dd739d5c09177950e7223;hb=e90b65284812aaa5ff9e9935ce9bbad7791cbbcd;hpb=12752486db3caad471e9f5094a3b644bbc5882f3 diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 713cef312f1..358d9add3a3 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -1,10 +1,10 @@ /* - Unix SMB/Netbios implementation. - Version 2.0 + Unix SMB/CIFS implementation. Winbind daemon for ntdom nss module - Copyright (C) Tim Potter 2000 + 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 @@ -23,31 +23,38 @@ #include "winbindd.h" -pstring servicesf = CONFIGFILE; - /* List of all connected clients */ struct winbindd_cli_state *client_list; static int num_clients; +BOOL opt_nocache = False; +BOOL opt_dual_daemon = False; /* Reload configuration */ static BOOL reload_services_file(BOOL test) { BOOL ret; + pstring logfile; if (lp_loaded()) { pstring fname; pstrcpy(fname,lp_configfile()); - if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) { - pstrcpy(servicesf,fname); + if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) { + pstrcpy(dyn_CONFIGFILE,fname); test = False; } } + snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE); + lp_set_logfile(logfile); + reopen_logs(); - ret = lp_load(servicesf,False,False,True); + ret = lp_load(dyn_CONFIGFILE,False,False,True); + + snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE); + lp_set_logfile(logfile); reopen_logs(); load_interfaces(); @@ -55,17 +62,68 @@ static BOOL reload_services_file(BOOL test) return(ret); } -static void winbindd_dump_status(void) +#if DUMP_CORE + +/**************************************************************************** ** + Prepare to dump a core file - carefully! + **************************************************************************** */ + +static BOOL dump_core(void) +{ + char *p; + pstring dname; + pstrcpy( dname, lp_logfile() ); + if ((p=strrchr(dname,'/'))) + *p=0; + pstrcat( dname, "/corefiles" ); + mkdir( dname, 0700 ); + sys_chown( dname, getuid(), getgid() ); + chmod( dname, 0700 ); + if ( chdir(dname) ) + return( False ); + umask( ~(0700) ); + +#ifdef HAVE_GETRLIMIT +#ifdef RLIMIT_CORE + { + struct rlimit rlp; + getrlimit( RLIMIT_CORE, &rlp ); + rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur ); + setrlimit( RLIMIT_CORE, &rlp ); + getrlimit( RLIMIT_CORE, &rlp ); + DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) ); + } +#endif +#endif + + DEBUG(0,("Dumping core in %s\n",dname)); + abort(); + return( True ); +} /* dump_core */ +#endif + +/**************************************************************************** ** + Handle a fault.. + **************************************************************************** */ + +static void fault_quit(void) +{ +#if DUMP_CORE + dump_core(); +#endif +} + +static void winbindd_status(void) { struct winbindd_cli_state *tmp; - DEBUG(0, ("Global status for winbindd:\n")); + DEBUG(0, ("winbindd status:\n")); /* Print client state information */ DEBUG(0, ("\t%d clients currently active\n", num_clients)); - if (DEBUGLEVEL >= 2) { + if (DEBUGLEVEL >= 2 && num_clients) { DEBUG(2, ("\tclient list:\n")); for(tmp = client_list; tmp; tmp = tmp->next) { DEBUG(2, ("\t\tpid %d, sock %d, rbl %d, wbl %d\n", @@ -77,201 +135,137 @@ static void winbindd_dump_status(void) /* Print winbindd status to log file */ -static void do_print_winbindd_status(void) +static void print_winbindd_status(void) { - winbindd_dump_status(); - winbindd_idmap_dump_status(); - winbindd_cache_dump_status(); + winbindd_status(); + winbindd_idmap_status(); + winbindd_cm_status(); } /* Flush client cache */ -static void do_flush_caches(void) +static void flush_caches(void) { - /* Clear cached user and group enumation info */ - - winbindd_flush_cache(); + /* Clear cached user and group enumation info */ + wcache_flush_cache(); } /* Handle the signal by unlinking socket and exiting */ -static void termination_handler(int signum) +static void terminate(void) { pstring path; + + winbindd_idmap_close(); /* Remove socket file */ - snprintf(path, sizeof(path), "%s/%s", WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME); unlink(path); - exit(0); } -static BOOL print_winbindd_status; +static BOOL do_sigterm; -static void sigusr1_handler(int signum) +static void termination_handler(int signum) { - BlockSignals(True, SIGUSR1); - print_winbindd_status = True; - BlockSignals(False, SIGUSR1); + 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) { - BlockSignals(True, SIGHUP); do_sighup = True; - BlockSignals(False, SIGHUP); + sys_select_signal(); } /* Create winbindd socket */ static int create_sock(void) { - struct sockaddr_un sunaddr; - struct stat st; - int sock; - mode_t old_umask; - pstring path; - - /* Create the socket directory or reuse the existing one */ - - if (lstat(WINBINDD_SOCKET_DIR, &st) == -1) { - - if (errno == ENOENT) { - - /* Create directory */ - - if (mkdir(WINBINDD_SOCKET_DIR, 0755) == -1) { - DEBUG(0, ("error creating socket directory %s: %s\n", - WINBINDD_SOCKET_DIR, strerror(errno))); - return -1; - } - - } else { - - DEBUG(0, ("lstat failed on socket directory %s: %s\n", - WINBINDD_SOCKET_DIR, strerror(errno))); - return -1; - } - - } else { - - /* Check ownership and permission on existing directory */ - - if (!S_ISDIR(st.st_mode)) { - DEBUG(0, ("socket directory %s isn't a directory\n", - WINBINDD_SOCKET_DIR)); - return -1; - } - - if ((st.st_uid != sec_initial_uid()) || - ((st.st_mode & 0777) != 0755)) { - DEBUG(0, ("invalid permissions on socket directory %s\n", - WINBINDD_SOCKET_DIR)); - return -1; - } - } - - /* Create the socket file */ - - old_umask = umask(0); - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - - if (sock == -1) { - perror("socket"); - return -1; - } - - snprintf(path, sizeof(path), "%s/%s", - WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME); - - unlink(path); - memset(&sunaddr, 0, sizeof(sunaddr)); - sunaddr.sun_family = AF_UNIX; - safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1); - - if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) { - DEBUG(0, ("bind failed on winbind socket %s: %s\n", - path, - strerror(errno))); - close(sock); - return -1; - } - - if (listen(sock, 5) == -1) { - DEBUG(0, ("listen failed on winbind socket %s: %s\n", - path, - strerror(errno))); - close(sock); - return -1; - } - - umask(old_umask); - - /* Success! */ - - return sock; + return create_pipe_sock( WINBINDD_SOCKET_DIR, + WINBINDD_SOCKET_NAME, 0755); } struct dispatch_table { enum winbindd_cmd cmd; enum winbindd_result (*fn)(struct winbindd_cli_state *state); + char *winbindd_cmd_name; }; static struct dispatch_table dispatch_table[] = { /* User functions */ - { WINBINDD_GETPWNAM_FROM_USER, winbindd_getpwnam_from_user }, - { WINBINDD_GETPWNAM_FROM_UID, winbindd_getpwnam_from_uid }, - { WINBINDD_SETPWENT, winbindd_setpwent }, - { WINBINDD_ENDPWENT, winbindd_endpwent }, - { WINBINDD_GETPWENT, winbindd_getpwent }, - { WINBINDD_GETGROUPS, winbindd_getgroups }, + { WINBINDD_GETPWNAM, winbindd_getpwnam, "GETPWNAM" }, + { WINBINDD_GETPWUID, winbindd_getpwuid, "GETPWUID" }, + + { WINBINDD_SETPWENT, winbindd_setpwent, "SETPWENT" }, + { WINBINDD_ENDPWENT, winbindd_endpwent, "ENDPWENT" }, + { WINBINDD_GETPWENT, winbindd_getpwent, "GETPWENT" }, + + { WINBINDD_GETGROUPS, winbindd_getgroups, "GETGROUPS" }, /* Group functions */ - { WINBINDD_GETGRNAM_FROM_GROUP, winbindd_getgrnam_from_group }, - { WINBINDD_GETGRNAM_FROM_GID, winbindd_getgrnam_from_gid }, - { WINBINDD_SETGRENT, winbindd_setgrent }, - { WINBINDD_ENDGRENT, winbindd_endgrent }, - { WINBINDD_GETGRENT, winbindd_getgrent }, + { WINBINDD_GETGRNAM, winbindd_getgrnam, "GETGRNAM" }, + { WINBINDD_GETGRGID, winbindd_getgrgid, "GETGRGID" }, + { WINBINDD_SETGRENT, winbindd_setgrent, "SETGRENT" }, + { WINBINDD_ENDGRENT, winbindd_endgrent, "ENDGRENT" }, + { WINBINDD_GETGRENT, winbindd_getgrent, "GETGRENT" }, + { WINBINDD_GETGRLST, winbindd_getgrent, "GETGRLST" }, /* PAM auth functions */ - { WINBINDD_PAM_AUTH, winbindd_pam_auth }, - { WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap }, - { WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok }, + { WINBINDD_PAM_AUTH, winbindd_pam_auth, "PAM_AUTH" }, + { WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap, "AUTH_CRAP" }, + { WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok, "CHAUTHTOK" }, /* Enumeration functions */ - { WINBINDD_LIST_USERS, winbindd_list_users }, - { WINBINDD_LIST_GROUPS, winbindd_list_groups }, - { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains }, + { 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_LOOKUPSID, winbindd_lookupsid }, - { WINBINDD_LOOKUPNAME, winbindd_lookupname }, + { WINBINDD_LOOKUPSID, winbindd_lookupsid, "LOOKUPSID" }, + { WINBINDD_LOOKUPNAME, winbindd_lookupname, "LOOKUPNAME" }, - /* S*RS related functions */ + /* Lookup related functions */ - { WINBINDD_SID_TO_UID, winbindd_sid_to_uid }, - { WINBINDD_SID_TO_GID, winbindd_sid_to_gid }, - { WINBINDD_GID_TO_SID, winbindd_gid_to_sid }, - { WINBINDD_UID_TO_SID, winbindd_uid_to_sid }, + { WINBINDD_SID_TO_UID, winbindd_sid_to_uid, "SID_TO_UID" }, + { WINBINDD_SID_TO_GID, winbindd_sid_to_gid, "SID_TO_GID" }, + { WINBINDD_GID_TO_SID, winbindd_gid_to_sid, "GID_TO_SID" }, + { WINBINDD_UID_TO_SID, winbindd_uid_to_sid, "UID_TO_SID" }, /* Miscellaneous */ - { WINBINDD_CHECK_MACHACC, winbindd_check_machine_acct }, + { WINBINDD_CHECK_MACHACC, winbindd_check_machine_acct, "CHECK_MACHACC" }, + { 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 */ - { WINBINDD_NUM_CMDS, NULL } + { WINBINDD_NUM_CMDS, NULL, "NONE" } }; static void process_request(struct winbindd_cli_state *state) @@ -281,7 +275,7 @@ static void process_request(struct winbindd_cli_state *state) /* Free response data - we may be interrupted and receive another command before being able to send this data off. */ - safe_free(state->response.extra_data); + SAFE_FREE(state->response.extra_data); ZERO_STRUCT(state->response); @@ -290,20 +284,21 @@ static void process_request(struct winbindd_cli_state *state) /* Process command */ - if (!server_state.lsa_handle_open) return; - for (table = dispatch_table; table->fn; table++) { if (state->request.cmd == table->cmd) { + DEBUG(10,("process_request: request fn %s\n", table->winbindd_cmd_name )); state->response.result = table->fn(state); break; } } + if (!table->fn) + DEBUG(10,("process_request: unknown request fn number %d\n", (int)state->request.cmd )); + /* In case extra data pointer is NULL */ - if (!state->response.extra_data) { + if (!state->response.extra_data) state->response.length = sizeof(struct winbindd_response); - } } /* Process a new connection by adding it to the client connection list */ @@ -318,21 +313,21 @@ static void new_connection(int accept_sock) /* Accept connection */ len = sizeof(sunaddr); - if ((sock = accept(accept_sock, (struct sockaddr *)&sunaddr, &len)) - == -1) { - + + do { + sock = accept(accept_sock, (struct sockaddr *)&sunaddr, &len); + } while (sock == -1 && errno == EINTR); + + if (sock == -1) return; - } DEBUG(6,("accepted socket %d\n", sock)); /* Create new connection structure */ - if ((state = (struct winbindd_cli_state *) - malloc(sizeof(*state))) == NULL) { - + if ((state = (struct winbindd_cli_state *) + malloc(sizeof(*state))) == NULL) return; - } ZERO_STRUCTP(state); state->sock = sock; @@ -363,19 +358,20 @@ static void remove_client(struct winbindd_cli_state *state) /* We may have some extra data that was not freed if the client was killed unexpectedly */ - safe_free(state->response.extra_data); + SAFE_FREE(state->response.extra_data); /* Remove from list and free */ DLIST_REMOVE(client_list, state); - free(state); + SAFE_FREE(state); num_clients--; } } + /* 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 */ @@ -387,19 +383,31 @@ static void process_packet(struct winbindd_cli_state *state) 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; /* Read data */ - n = read(state->sock, state->read_buf_len + (char *)&state->request, - sizeof(state->request) - state->read_buf_len); + do { + + n = read(state->sock, state->read_buf_len + + (char *)&state->request, + sizeof(state->request) - state->read_buf_len); + + } while (n == -1 && errno == EINTR); + DEBUG(10,("client_read: read %d bytes. Need %d more for a full request.\n", n, sizeof(state->request) - n - state->read_buf_len )); + /* Read failed, kill client */ if (n == -1 || n == 0) { @@ -442,8 +450,12 @@ static void client_write(struct winbindd_cli_state *state) state->write_buf_len; } - num_written = write(state->sock, data, state->write_buf_len); + do { + num_written = write(state->sock, data, state->write_buf_len); + } while (num_written == -1 && errno == EINTR); + DEBUG(10,("client_write: wrote %d bytes.\n", num_written )); + /* Write failed, kill cilent */ if (num_written == -1 || num_written == 0) { @@ -454,8 +466,7 @@ static void client_write(struct winbindd_cli_state *state) state->finished = True; - safe_free(state->response.extra_data); - state->response.extra_data = NULL; + SAFE_FREE(state->response.extra_data); return; } @@ -472,11 +483,12 @@ static void client_write(struct winbindd_cli_state *state) if (state->write_extra_data) { - safe_free(state->response.extra_data); - state->response.extra_data = NULL; + SAFE_FREE(state->response.extra_data); state->write_extra_data = False; + DEBUG(10,("client_write: client_write: complete response written.\n")); + } else if (state->response.length > sizeof(struct winbindd_response)) { @@ -486,6 +498,8 @@ static void client_write(struct winbindd_cli_state *state) state->response.length - sizeof(struct winbindd_response); + DEBUG(10,("client_write: need to write %d extra data bytes.\n", (int)state->write_buf_len)); + state->write_extra_data = True; } } @@ -506,13 +520,14 @@ static void process_loop(int accept_sock) int maxfd = accept_sock, selret; struct timeval timeout; - /* Free up temporary memory */ + /* Handle messages */ - lp_talloc_free(); + message_dispatch(); - /* Do any connection establishment that is needed */ + /* Free up temporary memory */ - establish_connections(False); /* Honour timeout */ + lp_talloc_free(); + main_loop_talloc_free(); /* Initialise fd lists for select() */ @@ -523,6 +538,10 @@ static void process_loop(int accept_sock) 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; @@ -542,51 +561,28 @@ static void process_loop(int accept_sock) /* Select requires we know the highest fd used */ - if (state->sock > maxfd) maxfd = state->sock; + if (state->sock > maxfd) + maxfd = state->sock; /* Add fd for reading */ - if (state->read_buf_len != sizeof(state->request)) { + if (state->read_buf_len != sizeof(state->request)) FD_SET(state->sock, &r_fds); - } /* Add fd for writing */ - if (state->write_buf_len) { + if (state->write_buf_len) FD_SET(state->sock, &w_fds); - } state = state->next; } - /* Check signal handling things */ - - if (do_sighup) { - - /* Flush winbindd cache */ - - do_flush_caches(); - reload_services_file(True); - - /* Close and re-open all connections. This will also - refresh the trusted domains list */ - - winbindd_kill_all_connections(); - establish_connections(True); /* Force re-establish */ - - do_sighup = False; - } - - if (print_winbindd_status) { - do_print_winbindd_status(); - print_winbindd_status = False; - } - /* 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) + continue; if ((selret == -1 && errno != EINTR) || selret == 0) { @@ -600,9 +596,12 @@ static void process_loop(int accept_sock) if (selret > 0) { - if (FD_ISSET(accept_sock, &r_fds)) { - new_connection(accept_sock); + if (opt_dual_daemon) { + dual_select(&w_fds); } + + if (FD_ISSET(accept_sock, &r_fds)) + new_connection(accept_sock); /* Process activity on client connections */ @@ -614,140 +613,271 @@ static void process_loop(int accept_sock) /* Read data */ - client_read(state); - + winbind_client_read(state); + + /* + * If we have the start of a + * packet, then check the + * length field to make sure + * the client's not talking + * Mock Swedish. + */ + + if (state->read_buf_len >= sizeof(uint32) + && *(uint32 *) &state->request != sizeof(state->request)) { + DEBUG(0,("process_loop: Invalid request size (%d) send, should be (%d)\n", + *(uint32 *) &state->request, sizeof(state->request))); + + remove_client(state); + break; + } + /* A request packet might be complete */ if (state->read_buf_len == sizeof(state->request)) { - process_packet(state); + winbind_process_packet(state); } } /* Data available for writing */ - if (FD_ISSET(state->sock, &w_fds)) { + if (FD_ISSET(state->sock, &w_fds)) client_write(state); - } } } + +#if 0 + winbindd_check_cache_size(time(NULL)); +#endif + + /* Check signal handling things */ + + if (do_sigterm) + terminate(); + + if (do_sighup) { + + /* Flush winbindd cache */ + + flush_caches(); + reload_services_file(True); + do_sighup = False; + } + + if (do_sigusr2) { + print_winbindd_status(); + do_sigusr2 = False; + } } } + +/* + 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 pstring debugf; + 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 + SIGUSR[12] is received before a handler is installed */ + + CatchSignal(SIGUSR1, SIG_IGN); + CatchSignal(SIGUSR2, SIG_IGN); + + fault_setup((void (*)(void *))fault_quit ); + + /* Append to log file by default as we are a single process daemon + program. */ + + append_log = True; + + snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE); + lp_set_logfile(logfile); + + /* Initialise for running in non-root mode */ sec_init(); /* 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 */ - while ((opt = getopt(argc, argv, "id:s:")) != EOF) { + while ((opt = getopt(argc, argv, "id:s:nhB")) != EOF) { switch (opt) { /* Don't become a daemon */ - case 'i': interactive = True; break; - /* Run with specified debug level */ + /* dual daemon system */ + case 'B': + opt_dual_daemon = True; + break; + + /* disable cacheing */ + case 'n': + opt_nocache = True; + break; + /* Run with specified debug level */ case 'd': - new_debuglevel = atoi(optarg); + DEBUGLEVEL = atoi(optarg); + AllowDebugChange = False; break; /* Load a different smb.conf file */ - case 's': - pstrcpy(servicesf,optarg); + pstrcpy(dyn_CONFIGFILE,optarg); break; + case 'h': + usage(); + exit(0); + default: printf("Unknown option %c\n", (char)opt); exit(1); } } - snprintf(debugf, sizeof(debugf), "%s/log.winbindd", LOGFILEBASE); + snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE); + lp_set_logfile(logfile); setup_logging("winbindd", interactive); reopen_logs(); + DEBUG(1, ("winbindd version %s started.\n", VERSION ) ); + DEBUGADD( 1, ( "Copyright The Samba Team 2000-2001\n" ) ); + + if (!reload_services_file(False)) { + DEBUG(0, ("error opening config file\n")); + exit(1); + } + + /* Setup names. */ + if (!*global_myname) { char *p; fstrcpy(global_myname, myhostname()); p = strchr(global_myname, '.'); - if (p) { + if (p) *p = 0; - } } - TimeInit(); - - if (!reload_services_file(False)) { - DEBUG(0, ("error opening config file\n")); - exit(1); - } - - if (new_debuglevel != -1) { - DEBUGLEVEL = new_debuglevel; - } + fstrcpy(global_myworkgroup, lp_workgroup()); if (!interactive) { become_daemon(); + pidfile_create("winbindd"); } - load_interfaces(); - - secrets_init(); - - ZERO_STRUCT(server_state); - - /* Winbind daemon initialisation */ - - if (!winbindd_param_init()) { - return 1; +#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(); } - if (!winbindd_idmap_init()) { + if (winbind_setup_common() != 0) { return 1; } - winbindd_cache_init(); - - /* 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, 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 */ + if (!message_init()) { + DEBUG(0, ("unable to initialise messaging system\n")); + exit(1); + } - CatchSignal(SIGUSR1, sigusr1_handler); /* Debugging sigs */ - CatchSignal(SIGHUP, sighup_handler); + register_msg_pool_usage(); /* Create UNIX domain socket */ @@ -760,5 +890,6 @@ int main(int argc, char **argv) process_loop(accept_sock); + uni_group_cache_shutdown(); return 0; }