diff options
Diffstat (limited to 'source/nsswitch/winbindd.c')
-rw-r--r-- | source/nsswitch/winbindd.c | 247 |
1 files changed, 148 insertions, 99 deletions
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c index 666472eddbe..5dc28a43695 100644 --- a/source/nsswitch/winbindd.c +++ b/source/nsswitch/winbindd.c @@ -1,5 +1,6 @@ /* - Unix SMB/CIFS implementation. + Unix SMB/Netbios implementation. + Version 3.0 Winbind daemon for ntdom nss module @@ -22,13 +23,12 @@ #include "winbindd.h" +pstring servicesf = CONFIGFILE; + /* List of all connected clients */ struct winbindd_cli_state *client_list; static int num_clients; -BOOL opt_nocache; - -pstring servicesf = CONFIGFILE; /* Reload configuration */ @@ -49,14 +49,12 @@ static BOOL reload_services_file(BOOL test) snprintf(logfile, sizeof(logfile), "%s/log.winbindd", LOGFILEBASE); lp_set_logfile(logfile); - reopen_logs(); ret = lp_load(servicesf,False,False,True); snprintf(logfile, sizeof(logfile), "%s/log.winbindd", LOGFILEBASE); lp_set_logfile(logfile); - reopen_logs(); load_interfaces(); @@ -140,6 +138,7 @@ static void print_winbindd_status(void) { winbindd_status(); winbindd_idmap_status(); + winbindd_cache_status(); winbindd_cm_status(); } @@ -147,8 +146,9 @@ static void print_winbindd_status(void) static void flush_caches(void) { - /* Clear cached user and group enumation info */ - wcache_flush_cache(); + /* Clear cached user and group enumation info */ + + winbindd_flush_cache(); } /* Handle the signal by unlinking socket and exiting */ @@ -156,9 +156,10 @@ static void flush_caches(void) static void terminate(void) { pstring path; - - winbindd_idmap_close(); + /* Close idmap. */ + winbindd_idmap_close(); + /* Remove socket file */ snprintf(path, sizeof(path), "%s/%s", WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME); @@ -174,11 +175,11 @@ static void termination_handler(int signum) sys_select_signal(); } -static BOOL do_sigusr2; +static BOOL do_sigusr1; -static void sigusr2_handler(int signum) +static void sigusr1_handler(int signum) { - do_sigusr2 = True; + do_sigusr1 = True; sys_select_signal(); } @@ -194,8 +195,92 @@ static void sighup_handler(int signum) static int create_sock(void) { - return create_pipe_sock( WINBINDD_SOCKET_DIR, - WINBINDD_SOCKET_NAME, 0755); + 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; } struct dispatch_table { @@ -208,8 +293,8 @@ static struct dispatch_table dispatch_table[] = { /* User functions */ - { WINBINDD_GETPWNAM, winbindd_getpwnam, "GETPWNAM" }, - { WINBINDD_GETPWUID, winbindd_getpwuid, "GETPWUID" }, + { WINBINDD_GETPWNAM_FROM_USER, winbindd_getpwnam_from_user, "GETPWNAM_FROM_USER" }, + { WINBINDD_GETPWNAM_FROM_UID, winbindd_getpwnam_from_uid, "GETPWNAM_FROM_UID" }, { WINBINDD_SETPWENT, winbindd_setpwent, "SETPWENT" }, { WINBINDD_ENDPWENT, winbindd_endpwent, "ENDPWENT" }, @@ -219,8 +304,8 @@ static struct dispatch_table dispatch_table[] = { /* Group functions */ - { WINBINDD_GETGRNAM, winbindd_getgrnam, "GETGRNAM" }, - { WINBINDD_GETGRGID, winbindd_getgrgid, "GETGRGID" }, + { WINBINDD_GETGRNAM_FROM_GROUP, winbindd_getgrnam_from_group, "GETGRNAM_FROM_GROUP" }, + { WINBINDD_GETGRNAM_FROM_GID, winbindd_getgrnam_from_gid, "GETGRNAM_FROM_GID" }, { WINBINDD_SETGRENT, winbindd_setgrent, "SETGRENT" }, { WINBINDD_ENDGRENT, winbindd_endgrent, "ENDGRENT" }, { WINBINDD_GETGRENT, winbindd_getgrent, "GETGRENT" }, @@ -228,7 +313,9 @@ static struct dispatch_table dispatch_table[] = { /* PAM auth functions */ { WINBINDD_PAM_AUTH, winbindd_pam_auth, "PAM_AUTH" }, +#if ALLOW_WINBIND_AUTH_CRAP { WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap, "AUTH_CRAP" }, +#endif { WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok, "CHAUTHTOK" }, /* Enumeration functions */ @@ -236,7 +323,6 @@ static struct dispatch_table dispatch_table[] = { { 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 */ @@ -253,15 +339,11 @@ static struct dispatch_table dispatch_table[] = { /* Miscellaneous */ { 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" }, + { WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" }, + { WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" }, /* End of list */ @@ -393,15 +475,16 @@ static void client_read(struct winbindd_cli_state *state) /* Read data */ do { - - n = read(state->sock, state->read_buf_len + - (char *)&state->request, - sizeof(state->request) - state->read_buf_len); - + 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) { - /* Read failed, kill client */ DEBUG(5,("read failed on sock %d, pid %d: %s\n", state->sock, state->pid, (n == -1) ? strerror(errno) : "EOF")); @@ -410,8 +493,6 @@ static void client_read(struct winbindd_cli_state *state) return; } - DEBUG(10,("client_read: read %d bytes. Need %d more for a full request.\n", n, sizeof(state->request) - n - state->read_buf_len )); - /* Update client state */ state->read_buf_len += n; @@ -513,14 +594,9 @@ static void process_loop(int accept_sock) 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() */ @@ -600,6 +676,8 @@ static void process_loop(int accept_sock) client_read(state); +#if 0 + /* JRA - currently there's no length field in the request... */ /* * If we have the start of a * packet, then check the @@ -608,14 +686,19 @@ static void process_loop(int accept_sock) * Mock Swedish. */ - if (state->read_buf_len >= sizeof(uint32) - && *(uint32 *) &state->request != sizeof(state->request)) { + if (state->read_buf_len >= sizeof(int) + && *(int *) state->buf != sizeof(state->request)) { + + struct winbindd_cli_state *rem_state = state; + DEBUG(0,("process_loop: Invalid request size (%d) send, should be (%d)\n", - *(uint32 *) &state->request, sizeof(state->request))); + *(int *) rem_state->buf, sizeof(rem_state->request) )); - remove_client(state); - break; + state = state_next; + remove_client(rem_state); + continue; } +#endif /* A request packet might be complete */ @@ -633,10 +716,6 @@ static void process_loop(int accept_sock) } } -#if 0 - winbindd_check_cache_size(time(NULL)); -#endif - /* Check signal handling things */ if (do_sigterm) @@ -651,9 +730,9 @@ static void process_loop(int accept_sock) do_sighup = False; } - if (do_sigusr2) { + if (do_sigusr1) { print_winbindd_status(); - do_sigusr2 = False; + do_sigusr1 = False; } } } @@ -662,33 +741,20 @@ static void process_loop(int accept_sock) struct winbindd_state server_state; /* Server state information */ - -static void usage(void) -{ - printf("Usage: winbindd [options]\n"); - printf("\t-i interactive 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; + int opt, new_debuglevel = -1; /* glibc (?) likes to print "User defined signal 1" and exit if a - SIGUSR[12] is received before a handler is installed */ + SIGUSR1 is received before a handler is installed */ CatchSignal(SIGUSR1, SIG_IGN); - CatchSignal(SIGUSR2, SIG_IGN); TimeInit(); @@ -707,40 +773,34 @@ int main(int argc, char **argv) /* Initialise samba/rpc client stuff */ - while ((opt = getopt(argc, argv, "id:s:nh")) != EOF) { + while ((opt = getopt(argc, argv, "id:s:")) != EOF) { switch (opt) { - /* Don't become a daemon */ + /* Don't become a daemon */ + case 'i': interactive = True; break; - /* disable cacheing */ - case 'n': - opt_nocache = True; - break; - /* Run with specified debug level */ + case 'd': - DEBUGLEVEL = atoi(optarg); - AllowDebugChange = False; + new_debuglevel = atoi(optarg); break; /* Load a different smb.conf file */ + case 's': pstrcpy(servicesf,optarg); break; - case 'h': - usage(); - exit(0); - default: printf("Unknown option %c\n", (char)opt); exit(1); } } + /* Append to log file by default as we are a single process daemon program. */ @@ -748,7 +808,6 @@ int main(int argc, char **argv) snprintf(logfile, sizeof(logfile), "%s/log.winbindd", LOGFILEBASE); lp_set_logfile(logfile); - setup_logging("winbindd", interactive); reopen_logs(); @@ -760,12 +819,9 @@ int main(int argc, char **argv) exit(1); } - pidfile_create("winbindd"); - codepage_initialise(lp_client_code_page()); /* Setup names. */ - if (!*global_myname) { char *p; @@ -775,7 +831,10 @@ int main(int argc, char **argv) *p = 0; } - fstrcpy(global_myworkgroup, lp_workgroup()); + fstrcpy(global_myworkgroup, lp_workgroup()); + + if (new_debuglevel != -1) + DEBUGLEVEL = new_debuglevel; if (!interactive) become_daemon(); @@ -794,10 +853,10 @@ int main(int argc, char **argv) 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. */ + domain which we are a member of as well as any trusted + domains. */ - init_domain_list(); + get_domain_info(); ZERO_STRUCT(server_state); @@ -809,6 +868,8 @@ int main(int argc, char **argv) if (!winbindd_idmap_init()) return 1; + winbindd_cache_init(); + /* Unblock all signals we are interested in as they may have been blocked by the parent process. */ @@ -816,7 +877,6 @@ int main(int argc, char **argv) BlockSignals(False, SIGQUIT); BlockSignals(False, SIGTERM); BlockSignals(False, SIGUSR1); - BlockSignals(False, SIGUSR2); BlockSignals(False, SIGHUP); /* Setup signal handlers */ @@ -827,16 +887,9 @@ int main(int argc, char **argv) CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */ - CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */ + CatchSignal(SIGUSR1, sigusr1_handler); /* Debugging sigs */ CatchSignal(SIGHUP, sighup_handler); - /* Initialise messaging system */ - - if (!message_init()) { - DEBUG(0, ("unable to initialise messaging system\n")); - exit(1); - } - /* Create UNIX domain socket */ if ((accept_sock = create_sock()) == -1) { @@ -848,9 +901,5 @@ int main(int argc, char **argv) process_loop(accept_sock); -#if 0 - uni_group_cache_shutdown(); -#endif - return 0; } |