Updates to the NTLMSSP code again - moving the base64 decode fuctionality out
[abartlet/samba.git/.git] / source3 / nsswitch / winbindd.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Winbind daemon for ntdom nss module
5
6    Copyright (C) by Tim Potter 2000-2002
7    Copyright (C) Andrew Tridgell 2002
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "winbindd.h"
25
26 BOOL opt_nocache = False;
27 BOOL opt_dual_daemon = False;
28
29 /* Reload configuration */
30
31 static BOOL reload_services_file(BOOL test)
32 {
33         BOOL ret;
34         pstring logfile;
35
36         if (lp_loaded()) {
37                 pstring fname;
38
39                 pstrcpy(fname,lp_configfile());
40                 if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {
41                         pstrcpy(dyn_CONFIGFILE,fname);
42                         test = False;
43                 }
44         }
45
46         snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE);
47         lp_set_logfile(logfile);
48
49         reopen_logs();
50         ret = lp_load(dyn_CONFIGFILE,False,False,True);
51
52         snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE);
53         lp_set_logfile(logfile);
54
55         reopen_logs();
56         load_interfaces();
57
58         return(ret);
59 }
60
61 /*******************************************************************
62  Print out all talloc memory info.
63 ********************************************************************/
64
65 void return_all_talloc_info(int msg_type, pid_t src_pid, void *buf, size_t len)
66 {
67         TALLOC_CTX *ctx = talloc_init("info context");
68         char *info = NULL;
69
70         if (!ctx)
71                 return;
72
73         info = talloc_describe_all(ctx);
74         if (info)
75                 DEBUG(10,(info));
76         message_send_pid(src_pid, MSG_TALLOC_USAGE, info, info ? strlen(info) + 1: 0, True);
77         talloc_destroy(ctx);
78 }
79
80 #if DUMP_CORE
81
82 /**************************************************************************** **
83  Prepare to dump a core file - carefully!
84  **************************************************************************** */
85
86 static BOOL dump_core(void)
87 {
88         char *p;
89         pstring dname;
90         pstrcpy( dname, lp_logfile() );
91         if ((p=strrchr(dname,'/')))
92                 *p=0;
93         pstrcat( dname, "/corefiles" );
94         mkdir( dname, 0700 );
95         sys_chown( dname, getuid(), getgid() );
96         chmod( dname, 0700 );
97         if ( chdir(dname) )
98                 return( False );
99         umask( ~(0700) );
100  
101 #ifdef HAVE_GETRLIMIT
102 #ifdef RLIMIT_CORE
103         {
104                 struct rlimit rlp;
105                 getrlimit( RLIMIT_CORE, &rlp );
106                 rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
107                 setrlimit( RLIMIT_CORE, &rlp );
108                 getrlimit( RLIMIT_CORE, &rlp );
109                 DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
110         }
111 #endif
112 #endif
113  
114         DEBUG(0,("Dumping core in %s\n",dname));
115         abort();
116         return( True );
117 } /* dump_core */
118 #endif
119
120 /**************************************************************************** **
121  Handle a fault..
122  **************************************************************************** */
123
124 static void fault_quit(void)
125 {
126 #if DUMP_CORE
127         dump_core();
128 #endif
129 }
130
131 static void winbindd_status(void)
132 {
133         struct winbindd_cli_state *tmp;
134
135         DEBUG(0, ("winbindd status:\n"));
136
137         /* Print client state information */
138         
139         DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
140         
141         if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
142                 DEBUG(2, ("\tclient list:\n"));
143                 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
144                         DEBUG(2, ("\t\tpid %d, sock %d, rbl %d, wbl %d\n",
145                                   tmp->pid, tmp->sock, tmp->read_buf_len, 
146                                   tmp->write_buf_len));
147                 }
148         }
149 }
150
151 /* Print winbindd status to log file */
152
153 static void print_winbindd_status(void)
154 {
155         winbindd_status();
156         winbindd_idmap_status();
157         winbindd_cm_status();
158 }
159
160 /* Flush client cache */
161
162 static void flush_caches(void)
163 {
164         /* Clear cached user and group enumation info */        
165         wcache_flush_cache();
166 }
167
168 /* Handle the signal by unlinking socket and exiting */
169
170 static void terminate(void)
171 {
172         pstring path;
173
174         winbindd_idmap_close();
175         
176         /* Remove socket file */
177         snprintf(path, sizeof(path), "%s/%s", 
178                  WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
179         unlink(path);
180         exit(0);
181 }
182
183 static BOOL do_sigterm;
184
185 static void termination_handler(int signum)
186 {
187         do_sigterm = True;
188         sys_select_signal();
189 }
190
191 static BOOL do_sigusr2;
192
193 static void sigusr2_handler(int signum)
194 {
195         do_sigusr2 = True;
196         sys_select_signal();
197 }
198
199 static BOOL do_sighup;
200
201 static void sighup_handler(int signum)
202 {
203         do_sighup = True;
204         sys_select_signal();
205 }
206
207 struct dispatch_table {
208         enum winbindd_cmd cmd;
209         enum winbindd_result (*fn)(struct winbindd_cli_state *state);
210         const char *winbindd_cmd_name;
211 };
212
213 static struct dispatch_table dispatch_table[] = {
214         
215         /* User functions */
216
217         { WINBINDD_GETPWNAM, winbindd_getpwnam, "GETPWNAM" },
218         { WINBINDD_GETPWUID, winbindd_getpwuid, "GETPWUID" },
219
220         { WINBINDD_SETPWENT, winbindd_setpwent, "SETPWENT" },
221         { WINBINDD_ENDPWENT, winbindd_endpwent, "ENDPWENT" },
222         { WINBINDD_GETPWENT, winbindd_getpwent, "GETPWENT" },
223
224         { WINBINDD_GETGROUPS, winbindd_getgroups, "GETGROUPS" },
225
226         /* Group functions */
227
228         { WINBINDD_GETGRNAM, winbindd_getgrnam, "GETGRNAM" },
229         { WINBINDD_GETGRGID, winbindd_getgrgid, "GETGRGID" },
230         { WINBINDD_SETGRENT, winbindd_setgrent, "SETGRENT" },
231         { WINBINDD_ENDGRENT, winbindd_endgrent, "ENDGRENT" },
232         { WINBINDD_GETGRENT, winbindd_getgrent, "GETGRENT" },
233         { WINBINDD_GETGRLST, winbindd_getgrent, "GETGRLST" },
234
235         /* PAM auth functions */
236
237         { WINBINDD_PAM_AUTH, winbindd_pam_auth, "PAM_AUTH" },
238         { WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap, "AUTH_CRAP" },
239         { WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok, "CHAUTHTOK" },
240
241         /* Enumeration functions */
242
243         { WINBINDD_LIST_USERS, winbindd_list_users, "LIST_USERS" },
244         { WINBINDD_LIST_GROUPS, winbindd_list_groups, "LIST_GROUPS" },
245         { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains, "LIST_TRUSTDOM" },
246         { WINBINDD_SHOW_SEQUENCE, winbindd_show_sequence, "SHOW_SEQUENCE" },
247
248         /* SID related functions */
249
250         { WINBINDD_LOOKUPSID, winbindd_lookupsid, "LOOKUPSID" },
251         { WINBINDD_LOOKUPNAME, winbindd_lookupname, "LOOKUPNAME" },
252
253         /* Lookup related functions */
254
255         { WINBINDD_SID_TO_UID, winbindd_sid_to_uid, "SID_TO_UID" },
256         { WINBINDD_SID_TO_GID, winbindd_sid_to_gid, "SID_TO_GID" },
257         { WINBINDD_GID_TO_SID, winbindd_gid_to_sid, "GID_TO_SID" },
258         { WINBINDD_UID_TO_SID, winbindd_uid_to_sid, "UID_TO_SID" },
259
260         /* Miscellaneous */
261
262         { WINBINDD_CHECK_MACHACC, winbindd_check_machine_acct, "CHECK_MACHACC" },
263         { WINBINDD_PING, winbindd_ping, "PING" },
264         { WINBINDD_INFO, winbindd_info, "INFO" },
265         { WINBINDD_INTERFACE_VERSION, winbindd_interface_version, "INTERFACE_VERSION" },
266         { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
267         { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
268
269         /* WINS functions */
270
271         { WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },
272         { WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" },
273
274         /* End of list */
275
276         { WINBINDD_NUM_CMDS, NULL, "NONE" }
277 };
278
279 static void process_request(struct winbindd_cli_state *state)
280 {
281         struct dispatch_table *table = dispatch_table;
282
283         /* Free response data - we may be interrupted and receive another
284            command before being able to send this data off. */
285
286         SAFE_FREE(state->response.extra_data);  
287
288         ZERO_STRUCT(state->response);
289
290         state->response.result = WINBINDD_ERROR;
291         state->response.length = sizeof(struct winbindd_response);
292
293         /* Process command */
294
295         for (table = dispatch_table; table->fn; table++) {
296                 if (state->request.cmd == table->cmd) {
297                         DEBUG(10,("process_request: request fn %s\n", table->winbindd_cmd_name ));
298                         state->response.result = table->fn(state);
299                         break;
300                 }
301         }
302
303         if (!table->fn)
304                 DEBUG(10,("process_request: unknown request fn number %d\n", (int)state->request.cmd ));
305
306         /* In case extra data pointer is NULL */
307
308         if (!state->response.extra_data)
309                 state->response.length = sizeof(struct winbindd_response);
310 }
311
312 /* Process a new connection by adding it to the client connection list */
313
314 static void new_connection(int listen_sock)
315 {
316         struct sockaddr_un sunaddr;
317         struct winbindd_cli_state *state;
318         socklen_t len;
319         int sock;
320         
321         /* Accept connection */
322         
323         len = sizeof(sunaddr);
324
325         do {
326                 sock = accept(listen_sock, (struct sockaddr *)&sunaddr, &len);
327         } while (sock == -1 && errno == EINTR);
328
329         if (sock == -1)
330                 return;
331         
332         DEBUG(6,("accepted socket %d\n", sock));
333         
334         /* Create new connection structure */
335         
336         if ((state = (struct winbindd_cli_state *) 
337              malloc(sizeof(*state))) == NULL)
338                 return;
339         
340         ZERO_STRUCTP(state);
341         state->sock = sock;
342         
343         /* Add to connection list */
344         
345         winbindd_add_client(state);
346 }
347
348 /* Remove a client connection from client connection list */
349
350 static void remove_client(struct winbindd_cli_state *state)
351 {
352         /* It's a dead client - hold a funeral */
353         
354         if (state != NULL) {
355                 
356                 /* Close socket */
357                 
358                 close(state->sock);
359                 
360                 /* Free any getent state */
361                 
362                 free_getent_state(state->getpwent_state);
363                 free_getent_state(state->getgrent_state);
364                 
365                 /* We may have some extra data that was not freed if the
366                    client was killed unexpectedly */
367
368                 SAFE_FREE(state->response.extra_data);
369                 
370                 /* Remove from list and free */
371                 
372                 winbindd_remove_client(state);
373                 SAFE_FREE(state);
374         }
375 }
376
377
378 /* Process a complete received packet from a client */
379
380 void winbind_process_packet(struct winbindd_cli_state *state)
381 {
382         /* Process request */
383         
384         /* Ensure null termination of entire request */
385         state->request.null_term = '\0';
386
387         state->pid = state->request.pid;
388         
389         process_request(state);
390
391         /* Update client state */
392         
393         state->read_buf_len = 0;
394         state->write_buf_len = sizeof(struct winbindd_response);
395
396         /* we might need to send it to the dual daemon */
397         if (opt_dual_daemon) {
398                 dual_send_request(state);
399         }
400 }
401
402 /* Read some data from a client connection */
403
404 void winbind_client_read(struct winbindd_cli_state *state)
405 {
406         int n;
407     
408         /* Read data */
409
410         n = sys_read(state->sock, state->read_buf_len + 
411                  (char *)&state->request, 
412                  sizeof(state->request) - state->read_buf_len);
413         
414         DEBUG(10,("client_read: read %d bytes. Need %d more for a full request.\n", n, sizeof(state->request) - n - state->read_buf_len ));
415
416         /* Read failed, kill client */
417         
418         if (n == -1 || n == 0) {
419                 DEBUG(5,("read failed on sock %d, pid %d: %s\n",
420                          state->sock, state->pid, 
421                          (n == -1) ? strerror(errno) : "EOF"));
422                 
423                 state->finished = True;
424                 return;
425         }
426         
427         /* Update client state */
428         
429         state->read_buf_len += n;
430 }
431
432 /* Write some data to a client connection */
433
434 static void client_write(struct winbindd_cli_state *state)
435 {
436         char *data;
437         int num_written;
438         
439         /* Write some data */
440         
441         if (!state->write_extra_data) {
442
443                 /* Write response structure */
444                 
445                 data = (char *)&state->response + sizeof(state->response) - 
446                         state->write_buf_len;
447
448         } else {
449
450                 /* Write extra data */
451                 
452                 data = (char *)state->response.extra_data + 
453                         state->response.length - 
454                         sizeof(struct winbindd_response) - 
455                         state->write_buf_len;
456         }
457         
458         num_written = sys_write(state->sock, data, state->write_buf_len);
459         
460         DEBUG(10,("client_write: wrote %d bytes.\n", num_written ));
461
462         /* Write failed, kill cilent */
463         
464         if (num_written == -1 || num_written == 0) {
465                 
466                 DEBUG(3,("write failed on sock %d, pid %d: %s\n",
467                          state->sock, state->pid, 
468                          (num_written == -1) ? strerror(errno) : "EOF"));
469                 
470                 state->finished = True;
471
472                 SAFE_FREE(state->response.extra_data);
473
474                 return;
475         }
476         
477         /* Update client state */
478         
479         state->write_buf_len -= num_written;
480         
481         /* Have we written all data? */
482         
483         if (state->write_buf_len == 0) {
484                 
485                 /* Take care of extra data */
486                 
487                 if (state->write_extra_data) {
488
489                         SAFE_FREE(state->response.extra_data);
490
491                         state->write_extra_data = False;
492
493                         DEBUG(10,("client_write: client_write: complete response written.\n"));
494
495                 } else if (state->response.length > 
496                            sizeof(struct winbindd_response)) {
497                         
498                         /* Start writing extra data */
499
500                         state->write_buf_len = 
501                                 state->response.length -
502                                 sizeof(struct winbindd_response);
503                         
504                         DEBUG(10,("client_write: need to write %d extra data bytes.\n", (int)state->write_buf_len));
505
506                         state->write_extra_data = True;
507                 }
508         }
509 }
510
511 /* Process incoming clients on accept_sock.  We use a tricky non-blocking,
512    non-forking, non-threaded model which allows us to handle many
513    simultaneous connections while remaining impervious to many denial of
514    service attacks. */
515
516 static void process_loop(void)
517 {
518         /* We'll be doing this a lot */
519
520         while (1) {
521                 struct winbindd_cli_state *state;
522                 fd_set r_fds, w_fds;
523                 int maxfd, listen_sock, selret;
524                 struct timeval timeout;
525
526                 /* Handle messages */
527
528                 message_dispatch();
529
530                 /* rescan the trusted domains list. This must be done
531                    regularly to cope with transitive trusts */
532                 rescan_trusted_domains();
533
534                 /* Free up temporary memory */
535
536                 lp_talloc_free();
537                 main_loop_talloc_free();
538
539                 /* Initialise fd lists for select() */
540
541                 listen_sock = open_winbindd_socket();
542
543                 if (listen_sock == -1) {
544                         perror("open_winbind_socket");
545                         exit(1);
546                 }
547
548                 maxfd = listen_sock;
549
550                 FD_ZERO(&r_fds);
551                 FD_ZERO(&w_fds);
552                 FD_SET(listen_sock, &r_fds);
553
554                 timeout.tv_sec = WINBINDD_ESTABLISH_LOOP;
555                 timeout.tv_usec = 0;
556
557                 if (opt_dual_daemon) {
558                         maxfd = dual_select_setup(&w_fds, maxfd);
559                 }
560
561                 /* Set up client readers and writers */
562
563                 state = winbindd_client_list();
564
565                 while (state) {
566
567                         /* Dispose of client connection if it is marked as 
568                            finished */ 
569
570                         if (state->finished) {
571                                 struct winbindd_cli_state *next = state->next;
572
573                                 remove_client(state);
574                                 state = next;
575                                 continue;
576                         }
577
578                         /* Select requires we know the highest fd used */
579
580                         if (state->sock > maxfd)
581                                 maxfd = state->sock;
582
583                         /* Add fd for reading */
584
585                         if (state->read_buf_len != sizeof(state->request))
586                                 FD_SET(state->sock, &r_fds);
587
588                         /* Add fd for writing */
589
590                         if (state->write_buf_len)
591                                 FD_SET(state->sock, &w_fds);
592
593                         state = state->next;
594                 }
595
596                 /* Call select */
597         
598                 selret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
599
600                 if (selret == 0)
601                         continue;
602
603                 if ((selret == -1 && errno != EINTR) || selret == 0) {
604
605                         /* Select error, something is badly wrong */
606
607                         perror("select");
608                         exit(1);
609                 }
610
611                 /* Create a new connection if accept_sock readable */
612
613                 if (selret > 0) {
614
615                         if (opt_dual_daemon) {
616                                 dual_select(&w_fds);
617                         }
618
619                         if (FD_ISSET(listen_sock, &r_fds))
620                                 new_connection(listen_sock);
621             
622                         /* Process activity on client connections */
623             
624                         for (state = winbindd_client_list(); state; 
625                              state = state->next) {
626                 
627                                 /* Data available for reading */
628                 
629                                 if (FD_ISSET(state->sock, &r_fds)) {
630                     
631                                         /* Read data */
632                     
633                                         winbind_client_read(state);
634
635                                         /* 
636                                          * If we have the start of a
637                                          * packet, then check the
638                                          * length field to make sure
639                                          * the client's not talking
640                                          * Mock Swedish.
641                                          */
642
643                                         if (state->read_buf_len >= sizeof(uint32)
644                                             && *(uint32 *) &state->request != sizeof(state->request)) {
645                                                 DEBUG(0,("process_loop: Invalid request size from pid %d: %d bytes sent, should be %d\n",
646                                                                 state->request.pid, *(uint32 *) &state->request, sizeof(state->request)));
647
648                                                 remove_client(state);
649                                                 break;
650                                         }
651
652                                         /* A request packet might be 
653                                            complete */
654                     
655                                         if (state->read_buf_len == 
656                                             sizeof(state->request)) {
657                                                 winbind_process_packet(state);
658                                         }
659                                 }
660                 
661                                 /* Data available for writing */
662                 
663                                 if (FD_ISSET(state->sock, &w_fds))
664                                         client_write(state);
665                         }
666                 }
667
668 #if 0
669                 winbindd_check_cache_size(time(NULL));
670 #endif
671
672                 /* Check signal handling things */
673
674                 if (do_sigterm)
675                         terminate();
676
677                 if (do_sighup) {
678
679                         DEBUG(3, ("got SIGHUP\n"));
680  
681                         /* Flush various caches */
682
683                         flush_caches();
684                         reload_services_file(True);
685                         do_sighup = False;
686                 }
687
688                 if (do_sigusr2) {
689                         print_winbindd_status();
690                         do_sigusr2 = False;
691                 }
692         }
693 }
694
695
696 /*
697   these are split out from the main winbindd for use by the background daemon
698  */
699 BOOL winbind_setup_common(void)
700 {
701         load_interfaces();
702
703         if (!secrets_init()) {
704
705                 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
706                 return False;
707         }
708
709         namecache_enable();     /* Enable netbios namecache */
710
711         /* Check winbindd parameters are valid */
712
713         ZERO_STRUCT(server_state);
714
715         if (!winbindd_param_init())
716                 return False;
717
718         /* Winbind daemon initialisation */
719
720         if (!winbindd_idmap_init())
721                 return False;
722
723         /* Unblock all signals we are interested in as they may have been
724            blocked by the parent process. */
725
726         BlockSignals(False, SIGINT);
727         BlockSignals(False, SIGQUIT);
728         BlockSignals(False, SIGTERM);
729         BlockSignals(False, SIGUSR1);
730         BlockSignals(False, SIGUSR2);
731         BlockSignals(False, SIGHUP);
732
733         /* Setup signal handlers */
734         
735         CatchSignal(SIGINT, termination_handler);      /* Exit on these sigs */
736         CatchSignal(SIGQUIT, termination_handler);
737         CatchSignal(SIGTERM, termination_handler);
738
739         CatchSignal(SIGPIPE, SIG_IGN);                 /* Ignore sigpipe */
740
741         CatchSignal(SIGUSR2, sigusr2_handler);         /* Debugging sigs */
742         CatchSignal(SIGHUP, sighup_handler);
743
744         return True;
745 }
746
747
748 /* Main function */
749
750 struct winbindd_state server_state;   /* Server state information */
751
752
753 static void usage(void)
754 {
755         printf("Usage: winbindd [options]\n");
756         printf("\t-F                daemon in foreground mode\n");
757         printf("\t-S                log to stdout\n");
758         printf("\t-i                interactive mode\n");
759         printf("\t-B                dual daemon mode\n");
760         printf("\t-n                disable cacheing\n");
761         printf("\t-d level          set debug level\n");
762         printf("\t-s configfile     choose smb.conf location\n");
763         printf("\t-h                show this help message\n");
764 }
765
766  int main(int argc, char **argv)
767 {
768         extern BOOL AllowDebugChange;
769         pstring logfile;
770         BOOL interactive = False;
771         BOOL Fork = True;
772         BOOL log_stdout = False;
773         int opt;
774
775         /* glibc (?) likes to print "User defined signal 1" and exit if a
776            SIGUSR[12] is received before a handler is installed */
777
778         CatchSignal(SIGUSR1, SIG_IGN);
779         CatchSignal(SIGUSR2, SIG_IGN);
780
781         fault_setup((void (*)(void *))fault_quit );
782
783         snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE);
784         lp_set_logfile(logfile);
785
786         /* Initialise for running in non-root mode */
787
788         sec_init();
789
790         /* Set environment variable so we don't recursively call ourselves.
791            This may also be useful interactively. */
792
793         SETENV(WINBINDD_DONT_ENV, "1", 1);
794
795         /* Initialise samba/rpc client stuff */
796
797         while ((opt = getopt(argc, argv, "FSid:s:nhB")) != EOF) {
798                 switch (opt) {
799
800                 case 'F':
801                         Fork = False;
802                         break;
803                 case 'S':
804                         log_stdout = True;
805                         break;
806                         /* Don't become a daemon */
807                 case 'i':
808                         interactive = True;
809                         log_stdout = True;
810                         Fork = False;
811                         break;
812
813                         /* dual daemon system */
814                 case 'B':
815                         opt_dual_daemon = True;
816                         break;
817
818                         /* disable cacheing */
819                 case 'n':
820                         opt_nocache = True;
821                         break;
822
823                         /* Run with specified debug level */
824                 case 'd':
825                         DEBUGLEVEL = atoi(optarg);
826                         AllowDebugChange = False;
827                         break;
828
829                         /* Load a different smb.conf file */
830                 case 's':
831                         pstrcpy(dyn_CONFIGFILE,optarg);
832                         break;
833
834                 case 'h':
835                         usage();
836                         exit(0);
837
838                 default:
839                         printf("Unknown option %c\n", (char)opt);
840                         exit(1);
841                 }
842         }
843
844         if (log_stdout && Fork) {
845                 printf("Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n");
846                 usage();
847                 exit(1);
848         }
849
850         snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE);
851         lp_set_logfile(logfile);
852         setup_logging("winbindd", log_stdout);
853         reopen_logs();
854
855         DEBUG(1, ("winbindd version %s started.\n", VERSION ) );
856         DEBUGADD( 1, ( "Copyright The Samba Team 2000-2001\n" ) );
857
858         if (!reload_services_file(False)) {
859                 DEBUG(0, ("error opening config file\n"));
860                 exit(1);
861         }
862
863         /* Setup names. */
864
865         if (!init_names())
866                 exit(1);
867
868         if (!interactive) {
869                 become_daemon(Fork);
870                 pidfile_create("winbindd");
871         }
872
873
874 #if HAVE_SETPGID
875         /*
876          * If we're interactive we want to set our own process group for
877          * signal management.
878          */
879         if (interactive)
880                 setpgid( (pid_t)0, (pid_t)0);
881 #endif
882
883         if (!winbind_setup_common()) {
884                 return 1;
885         }
886
887         if (opt_dual_daemon) {
888                 do_dual_daemon();
889         }
890
891         /* Initialise messaging system */
892
893         if (!message_init()) {
894                 DEBUG(0, ("unable to initialise messaging system\n"));
895                 exit(1);
896         }
897
898         register_msg_pool_usage();
899         message_register(MSG_REQ_TALLOC_USAGE, return_all_talloc_info);
900
901         /* Loop waiting for requests */
902
903         process_loop();
904
905         trustdom_cache_shutdown();
906         uni_group_cache_shutdown();
907         return 0;
908 }