summaryrefslogtreecommitdiffstats
path: root/source/smbd/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/server.c')
-rw-r--r--source/smbd/server.c394
1 files changed, 147 insertions, 247 deletions
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 39d5e3bcd3f..14105342755 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -1,8 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Main SMB server routines
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Martin Pool 2002
+ Copyright (C) Andrew Tridgell 1992-1998
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
@@ -21,6 +21,7 @@
#include "includes.h"
+pstring servicesf = CONFIGFILE;
extern fstring global_myworkgroup;
extern pstring global_myname;
@@ -33,13 +34,13 @@ int last_message = -1;
#define LAST_MESSAGE() smb_fn_name(last_message)
extern pstring user_socket_options;
-extern SIG_ATOMIC_T got_sig_term;
-extern SIG_ATOMIC_T reload_after_sighup;
#ifdef WITH_DFS
extern int dcelogin_atmost_once;
#endif /* WITH_DFS */
+extern fstring remote_machine;
+
/* really we should have a top level context structure that has the
client file descriptor as an element. That would require a major rewrite :(
@@ -53,7 +54,7 @@ int smbd_server_fd(void)
return server_fd;
}
-static void smbd_set_server_fd(int fd)
+void smbd_set_server_fd(int fd)
{
server_fd = fd;
client_setfd(fd);
@@ -63,6 +64,8 @@ static void smbd_set_server_fd(int fd)
Terminate signal.
****************************************************************************/
+SIG_ATOMIC_T got_sig_term;
+
static void sig_term(void)
{
got_sig_term = 1;
@@ -73,6 +76,8 @@ static void sig_term(void)
Catch a sighup.
****************************************************************************/
+SIG_ATOMIC_T reload_after_sighup;
+
static void sig_hup(int sig)
{
reload_after_sighup = 1;
@@ -85,36 +90,8 @@ static void sig_hup(int sig)
static void killkids(void)
{
- if(am_parent) kill(0,SIGTERM);
-}
-
-/****************************************************************************
- Process a sam sync message - not sure whether to do this here or
- somewhere else.
-****************************************************************************/
-
-static void msg_sam_sync(int UNUSED(msg_type), pid_t UNUSED(pid),
- void *UNUSED(buf), size_t UNUSED(len))
-{
- DEBUG(10, ("** sam sync message received, ignoring\n"));
-}
-
-/****************************************************************************
- Process a sam sync replicate message - not sure whether to do this here or
- somewhere else.
-****************************************************************************/
-
-static void msg_sam_repl(int msg_type, pid_t pid, void *buf, size_t len)
-{
- uint32 low_serial;
-
- if (len != sizeof(uint32))
- return;
-
- low_serial = *((uint32 *)buf);
-
- DEBUG(3, ("received sam replication message, serial = 0x%04x\n",
- low_serial));
+ if(am_parent)
+ kill(0,SIGTERM);
}
/****************************************************************************
@@ -129,33 +106,25 @@ static BOOL open_sockets_inetd(void)
smbd_set_server_fd(dup(0));
/* close our standard file descriptors */
- close_low_fds(False); /* Don't close stderr */
+ close_low_fds();
set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
- set_socket_options(smbd_server_fd(), user_socket_options);
+ set_socket_options(smbd_server_fd(),user_socket_options);
return True;
}
-static void msg_exit_server(int msg_type, pid_t src, void *buf, size_t len)
-{
- exit_server("Got a SHUTDOWN message");
-}
-
-
/****************************************************************************
Open the socket communication.
****************************************************************************/
-static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
+static BOOL open_sockets(BOOL is_daemon,BOOL interactive, int port)
{
int num_interfaces = iface_count();
- int num_sockets = 0;
int fd_listenset[FD_SETSIZE];
fd_set listen_set;
int s;
int i;
- char *ports;
if (!is_daemon) {
return open_sockets_inetd();
@@ -174,112 +143,73 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
/* Stop zombies */
CatchChild();
-
+
+
FD_ZERO(&listen_set);
- /* use a reasonable default set of ports - listing on 445 and 139 */
- if (!smb_ports) {
- ports = lp_smb_ports();
- if (!ports || !*ports) {
- ports = SMB_PORTS;
- }
- ports = strdup(ports);
- } else {
- ports = strdup(smb_ports);
- }
-
- if (lp_interfaces() && lp_bind_interfaces_only()) {
+ if(lp_interfaces() && lp_bind_interfaces_only()) {
/* We have been given an interfaces line, and been
told to only bind to those interfaces. Create a
socket per interface and bind to only these.
*/
+ if(num_interfaces > FD_SETSIZE) {
+ DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
+max can be %d\n",
+ num_interfaces, FD_SETSIZE));
+ return False;
+ }
+
/* Now open a listen socket for each of the
interfaces. */
for(i = 0; i < num_interfaces; i++) {
struct in_addr *ifip = iface_n_ip(i);
- fstring tok;
- char *ptr;
-
+
if(ifip == NULL) {
- DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
+ DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
continue;
}
+ s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
+ if(s == -1)
+ return False;
- for (ptr=ports; next_token(&ptr, tok, NULL, sizeof(tok)); ) {
- unsigned port = atoi(tok);
- if (port == 0) continue;
- s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
- if(s == -1)
- return False;
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
-
- if (listen(s, 5) == -1) {
- DEBUG(0,("listen: %s\n",strerror(errno)));
- close(s);
- return False;
- }
- FD_SET(s,&listen_set);
+ /* ready to listen */
+ set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,user_socket_options);
- num_sockets++;
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
- return False;
- }
+ if (listen(s, 5) == -1) {
+ DEBUG(0,("listen: %s\n",strerror(errno)));
+ close(s);
+ return False;
}
+ FD_SET(s,&listen_set);
}
} else {
/* Just bind to 0.0.0.0 - accept connections
from anywhere. */
-
- fstring tok;
- char *ptr;
-
num_interfaces = 1;
- for (ptr=ports; next_token(&ptr, tok, NULL, sizeof(tok)); ) {
- unsigned port = atoi(tok);
- if (port == 0) continue;
- /* open an incoming socket */
- s = open_socket_in(SOCK_STREAM, port, 0,
- interpret_addr(lp_socket_address()),True);
- if (s == -1)
- return(False);
+ /* open an incoming socket */
+ s = open_socket_in(SOCK_STREAM, port, 0,
+ interpret_addr(lp_socket_address()),True);
+ if (s == -1)
+ return(False);
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
-
- if (listen(s, 5) == -1) {
- DEBUG(0,("open_sockets_smbd: listen: %s\n",
- strerror(errno)));
- close(s);
- return False;
- }
-
- fd_listenset[num_sockets] = s;
- FD_SET(s,&listen_set);
-
- num_sockets++;
-
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
- return False;
- }
+ /* ready to listen */
+ set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,user_socket_options);
+
+ if (listen(s, 5) == -1) {
+ DEBUG(0,("open_sockets: listen: %s\n",
+ strerror(errno)));
+ close(s);
+ return False;
}
+
+ fd_listenset[0] = s;
+ FD_SET(s,&listen_set);
}
- SAFE_FREE(ports);
-
- /* Listen to messages */
-
- message_register(MSG_SMB_SAM_SYNC, msg_sam_sync);
- message_register(MSG_SMB_SAM_REPL, msg_sam_repl);
- message_register(MSG_SHUTDOWN, msg_exit_server);
-
/* now accept incoming connections - forking a new process
for each incoming connection */
DEBUG(2,("waiting for a connection\n"));
@@ -305,10 +235,11 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
/* check for sighup processing */
if (reload_after_sighup) {
+ DEBUG(0,("Got SIGHUP\n"));
change_to_root_user();
DEBUG(1,("Reloading services after SIGHUP\n"));
reload_services(False);
- reload_after_sighup = 0;
+ reload_after_sighup = False;
}
continue;
@@ -324,7 +255,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
socklen_t in_addrlen = sizeof(addr);
s = -1;
- for(i = 0; i < num_sockets; i++) {
+ for(i = 0; i < num_interfaces; i++) {
if(FD_ISSET(fd_listenset[i],&lfds)) {
s = fd_listenset[i];
/* Clear this so we don't look
@@ -340,30 +271,29 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
continue;
if (smbd_server_fd() == -1) {
- DEBUG(0,("open_sockets_smbd: accept: %s\n",
+ DEBUG(0,("open_sockets: accept: %s\n",
strerror(errno)));
continue;
}
-
+
+ if (smbd_server_fd() != -1 && interactive)
+ return True;
+
if (smbd_server_fd() != -1 && sys_fork()==0) {
/* Child code ... */
/* close the listening socket(s) */
- for(i = 0; i < num_sockets; i++)
+ for(i = 0; i < num_interfaces; i++)
close(fd_listenset[i]);
/* close our standard file
descriptors */
- close_low_fds(False);
+ close_low_fds();
am_parent = 0;
set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
set_socket_options(smbd_server_fd(),user_socket_options);
- /* this is needed so that we get decent entries
- in smbstatus for port 445 connects */
- set_remote_machine_name(get_socket_addr(smbd_server_fd()));
-
/* Reset global variables in util.c so
that client substitutions will be
done correctly in the process. */
@@ -411,7 +341,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
/****************************************************************************
Reload the services file.
-**************************************************************************/
+ **************************************************************************/
BOOL reload_services(BOOL test)
{
@@ -420,9 +350,8 @@ BOOL reload_services(BOOL test)
if (lp_loaded()) {
pstring fname;
pstrcpy(fname,lp_configfile());
- if (file_exist(fname, NULL) &&
- !strcsequal(fname, dyn_CONFIGFILE)) {
- pstrcpy(dyn_CONFIGFILE, fname);
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
+ pstrcpy(servicesf,fname);
test = False;
}
}
@@ -434,7 +363,7 @@ BOOL reload_services(BOOL test)
lp_killunused(conn_snum_used);
- ret = lp_load(dyn_CONFIGFILE, False, False, True);
+ ret = lp_load(servicesf,False,False,True);
load_printers();
@@ -449,7 +378,7 @@ BOOL reload_services(BOOL test)
{
if (smbd_server_fd() != -1) {
set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
- set_socket_options(smbd_server_fd(), user_socket_options);
+ set_socket_options(smbd_server_fd(),user_socket_options);
}
}
@@ -464,15 +393,15 @@ BOOL reload_services(BOOL test)
#if DUMP_CORE
/*******************************************************************
-prepare to dump a core file - carefully!
+ Prepare to dump a core file - carefully !
********************************************************************/
+
static BOOL dump_core(void)
{
char *p;
pstring dname;
-
pstrcpy(dname,lp_logfile());
- if ((p=strrchr_m(dname,'/'))) *p=0;
+ if ((p=strrchr(dname,'/'))) *p=0;
pstrcat(dname,"/corefiles");
mkdir(dname,0700);
sys_chown(dname,getuid(),getgid());
@@ -495,7 +424,7 @@ static BOOL dump_core(void)
#endif
- DEBUG(0,("Dumping core in %s\n", dname));
+ DEBUG(0,("Dumping core in %s\n",dname));
abort();
return(True);
}
@@ -523,27 +452,21 @@ void exit_server(char *reason)
{
static int firsttime=1;
extern char *last_inbuf;
- extern struct auth_context *negprot_global_auth_context;
- if (!firsttime)
- exit(0);
+
+ if (!firsttime) exit(0);
firsttime = 0;
change_to_root_user();
DEBUG(2,("Closing connections\n"));
- if (negprot_global_auth_context) {
- (negprot_global_auth_context->free)(&negprot_global_auth_context);
- }
-
conn_close_all();
invalidate_all_vuids();
- print_notify_send_messages();
-
/* delete our entry in the connections database. */
- yield_connection(NULL,"");
+ if (lp_status(-1))
+ yield_connection(NULL,"");
respond_to_all_remaining_local_messages();
decrement_smbd_process_count();
@@ -568,7 +491,6 @@ void exit_server(char *reason)
}
locking_end();
- printing_end();
DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
exit(0);
@@ -587,13 +509,13 @@ static void init_structs(void )
if (!*global_myname) {
char *p;
- pstrcpy( global_myname, myhostname() );
- p = strchr_m(global_myname, '.' );
+ fstrcpy( global_myname, myhostname() );
+ p = strchr( global_myname, '.' );
if (p)
*p = 0;
}
- strupper(global_myname);
+ strupper( global_myname );
conn_init();
@@ -605,7 +527,6 @@ static void init_structs(void )
init_dptrs();
secrets_init();
-
}
/****************************************************************************
@@ -615,22 +536,21 @@ static void init_structs(void )
static void usage(char *pname)
{
- d_printf("Usage: %s [-DaioPh?Vb] [-d debuglevel] [-l log basename] [-p port]\n", pname);
- d_printf(" [-O socket options] [-s services file]\n");
- d_printf("\t-D Become a daemon (default)\n");
- d_printf("\t-a Append to log file (default)\n");
- d_printf("\t-i Run interactive (not a daemon)\n" );
- d_printf("\t-o Overwrite log file, don't append\n");
- d_printf("\t-h Print usage\n");
- d_printf("\t-? Print usage\n");
- d_printf("\t-V Print version\n");
- d_printf("\t-b Print build options\n");
- d_printf("\t-d debuglevel Set the debuglevel\n");
- d_printf("\t-l log basename. Basename for log/debug files\n");
- d_printf("\t-p port Listen on the specified port\n");
- d_printf("\t-O socket options Socket options\n");
- d_printf("\t-s services file. Filename of services file\n");
- d_printf("\n");
+ printf("Usage: %s [-DaioPh?V] [-d debuglevel] [-l log basename] [-p port]\n", pname);
+ printf(" [-O socket options] [-s services file]\n");
+ printf("\t-D Become a daemon (default)\n");
+ printf("\t-a Append to log file (default)\n");
+ printf("\t-i Run interactive (not a daemon)\n");
+ printf("\t-o Overwrite log file, don't append\n");
+ printf("\t-h Print usage\n");
+ printf("\t-? Print usage\n");
+ printf("\t-V Print version\n");
+ printf("\t-d debuglevel Set the debuglevel\n");
+ printf("\t-l log basename. Basename for log/debug files\n");
+ printf("\t-p port Listen on the specified port\n");
+ printf("\t-O socket options Socket options\n");
+ printf("\t-s services file. Filename of services file\n");
+ printf("\n");
}
/****************************************************************************
@@ -641,15 +561,15 @@ static void usage(char *pname)
{
extern BOOL append_log;
extern BOOL AllowDebugChange;
- extern char *optarg;
/* shall I run as a daemon */
BOOL is_daemon = False;
BOOL interactive = False;
BOOL specified_logfile = False;
- char *ports = NULL;
+ int port = SMB_PORT;
int opt;
+ extern char *optarg;
pstring logfile;
-
+
#ifdef HAVE_SET_AUTH_PARAMETERS
set_auth_parameters(argc,argv);
#endif
@@ -660,19 +580,19 @@ static void usage(char *pname)
argc--;
}
- while ( EOF != (opt = getopt(argc, argv, "O:l:s:d:Dp:h?bVaiof:")) )
+ while ( EOF != (opt = getopt(argc, argv, "O:l:s:d:Dip:h?Vaof:")) )
switch (opt) {
case 'O':
pstrcpy(user_socket_options,optarg);
break;
case 's':
- pstrcpy(dyn_CONFIGFILE,optarg);
+ pstrcpy(servicesf,optarg);
break;
case 'l':
specified_logfile = True;
- pstr_sprintf(logfile, "%s/log.smbd", optarg);
+ slprintf(logfile, sizeof(logfile)-1, "%s/log.smbd", optarg);
lp_set_logfile(logfile);
break;
@@ -680,10 +600,6 @@ static void usage(char *pname)
append_log = True;
break;
- case 'i':
- interactive = True;
- break;
-
case 'o':
append_log = False;
break;
@@ -692,6 +608,10 @@ static void usage(char *pname)
is_daemon = True;
break;
+ case 'i':
+ interactive = True;
+ break;
+
case 'd':
if (*optarg == 'A')
DEBUGLEVEL = 10000;
@@ -701,7 +621,7 @@ static void usage(char *pname)
break;
case 'p':
- ports = optarg;
+ port = atoi(optarg);
break;
case 'h':
@@ -711,11 +631,7 @@ static void usage(char *pname)
break;
case 'V':
- d_printf("Version %s\n",VERSION);
- exit(0);
- break;
- case 'b':
- build_options(True); /* Display output to screen as well as debug */
+ printf("Version %s\n",VERSION);
exit(0);
break;
default:
@@ -731,19 +647,21 @@ static void usage(char *pname)
sec_init();
- load_case_tables();
-
append_log = True;
+ TimeInit();
+
if(!specified_logfile) {
- pstr_sprintf(logfile, "%s/log.smbd", dyn_LOGFILEBASE);
+ slprintf(logfile, sizeof(logfile)-1, "%s/log.smbd", LOGFILEBASE);
lp_set_logfile(logfile);
}
- set_remote_machine_name("smbd");
+ pstrcpy(remote_machine, "smbd");
setup_logging(argv[0],interactive);
+ charset_initialise();
+
/* we want to re-seed early to prevent time delays causing
client problems at a later date. (tridge) */
generate_random_buffer(NULL, 0, False);
@@ -757,7 +675,7 @@ static void usage(char *pname)
fault_setup((void (*)(void *))exit_server);
CatchSignal(SIGTERM , SIGNAL_CAST sig_term);
CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
-
+
/* we are never interested in SIGPIPE */
BlockSignals(True,SIGPIPE);
@@ -782,6 +700,7 @@ static void usage(char *pname)
umask(0);
init_sec_ctx();
+ init_conn_ctx();
reopen_logs();
@@ -791,9 +710,6 @@ static void usage(char *pname)
DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
(int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
- /* Output the build options to the debug log */
- build_options(False);
-
if (sizeof(uint16) < 2 || sizeof(uint32) < 4) {
DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
exit(1);
@@ -807,13 +723,24 @@ static void usage(char *pname)
return(-1);
init_structs();
-
+
#ifdef WITH_PROFILE
if (!profile_setup(False)) {
- DEBUG(0,("ERROR: failed to setup profiling\n"));
+ DEBUG(0,("ERROR: failed to setup profiling shared memory\n"));
return -1;
}
-#endif
+#endif /* WITH_PROFILE */
+
+#ifdef WITH_SSL
+ {
+ extern BOOL sslEnabled;
+ sslEnabled = lp_ssl_enabled();
+ if(sslEnabled)
+ sslutil_init(True);
+ }
+#endif /* WITH_SSL */
+
+ codepage_initialise(lp_client_code_page());
fstrcpy(global_myworkgroup, lp_workgroup());
@@ -845,39 +772,35 @@ static void usage(char *pname)
setpgid( (pid_t)0, (pid_t)0);
#endif
- if (!directory_exist(lp_lockdir(), NULL)) {
+ if (!directory_exist(lp_lockdir(), NULL))
mkdir(lp_lockdir(), 0755);
- }
- if (is_daemon) {
+ if (is_daemon)
pidfile_create("smbd");
- }
- if (!message_init()) {
+ if (!message_init())
exit(1);
- }
- register_msg_pool_usage();
- register_dmalloc_msgs();
/* Setup the main smbd so that we can get messages. */
- claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD);
+ if (lp_status(-1))
+ claim_connection(NULL,"",0,True);
+
+ /* Attempt to migrate from an old 2.0.x machine account file. */
+ if (!migrate_from_old_password_file(global_myworkgroup))
+ DEBUG(0,("Failed to migrate from old MAC file.\n"));
- /*
- DO NOT ENABLE THIS TILL YOU COPE WITH KILLING THESE TASKS AND INETD
- THIS *killed* LOTS OF BUILD FARM MACHINES. IT CREATED HUNDREDS OF
- smbd PROCESSES THAT NEVER DIE
- start_background_queue();
- */
+ if(!pdb_generate_sam_sid()) {
+ DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
+ exit(1);
+ }
- if (!open_sockets_smbd(is_daemon,ports))
+ if (!open_sockets(is_daemon,interactive,port))
exit(1);
/*
- * everything after this point is run after the fork()
+ * Everything after this point is run after the fork().
*/
- namecache_enable();
-
if (!locking_init(0))
exit(1);
@@ -887,27 +810,12 @@ static void usage(char *pname)
if (!share_info_db_init())
exit(1);
- if (!init_registry())
- exit(1);
-
if(!initialize_password_db(False))
exit(1);
- uni_group_cache_init(); /* Non-critical */
-
/* possibly reload the services file. */
reload_services(True);
- if(!get_global_sam_sid()) {
- DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
- exit(1);
- }
-
- if (!init_account_policy()) {
- DEBUG(0,("Could not open account policy tdb.\n"));
- exit(1);
- }
-
if (*lp_rootdir()) {
if (sys_chroot(lp_rootdir()) == 0)
DEBUG(2,("Changed root to %s\n", lp_rootdir()));
@@ -916,21 +824,13 @@ static void usage(char *pname)
/* Setup oplocks */
if (!init_oplocks())
exit(1);
-
+
/* Setup change notify */
if (!init_change_notify())
exit(1);
- /* re-initialise the timezone */
- TimeInit();
-
- /* register our message handlers */
- message_register(MSG_SMB_FORCE_TDIS, msg_force_tdis);
- talloc_init_named("dummy!");
-
smbd_process();
- uni_group_cache_shutdown();
exit_server("normal exit");
return(0);
}