summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/aio.c181
-rw-r--r--source3/smbd/close.c20
-rw-r--r--source3/smbd/conn.c1
-rw-r--r--source3/smbd/connection.c32
-rw-r--r--source3/smbd/error.c8
-rw-r--r--source3/smbd/files.c1
-rw-r--r--source3/smbd/notify.c7
-rw-r--r--source3/smbd/open.c4
-rw-r--r--source3/smbd/oplock.c2
-rw-r--r--source3/smbd/pipes.c2
-rw-r--r--source3/smbd/process.c29
-rw-r--r--source3/smbd/reply.c28
-rw-r--r--source3/smbd/seal.c703
-rw-r--r--source3/smbd/server.c246
-rw-r--r--source3/smbd/service.c18
-rw-r--r--source3/smbd/session.c5
-rw-r--r--source3/smbd/sockinit.c211
-rw-r--r--source3/smbd/srvstr.c2
-rw-r--r--source3/smbd/trans2.c49
-rw-r--r--source3/smbd/utmp.c4
20 files changed, 389 insertions, 1164 deletions
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index 49855796b7..6ee0fe16e1 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -48,10 +48,8 @@ static struct aio_extra *aio_list_head;
of the aio_read call.
*****************************************************************************/
-static struct aio_extra *create_aio_ex_read(files_struct *fsp,
- size_t buflen,
- uint16 mid,
- const uint8 *inbuf)
+static struct aio_extra *create_aio_ex_read(files_struct *fsp, size_t buflen,
+ uint16 mid)
{
struct aio_extra *aio_ex = SMB_MALLOC_P(struct aio_extra);
@@ -67,14 +65,6 @@ static struct aio_extra *create_aio_ex_read(files_struct *fsp,
SAFE_FREE(aio_ex);
return NULL;
}
- /* Save the first 8 bytes of inbuf for possible enc data. */
- aio_ex->inbuf = SMB_MALLOC_ARRAY(char, 8);
- if (!aio_ex->inbuf) {
- SAFE_FREE(aio_ex->outbuf);
- SAFE_FREE(aio_ex);
- return NULL;
- }
- memcpy(aio_ex->inbuf, inbuf, 8);
DLIST_ADD(aio_list_head, aio_ex);
aio_ex->fsp = fsp;
aio_ex->read_req = True;
@@ -240,14 +230,13 @@ BOOL schedule_aio_read_and_X(connection_struct *conn,
bufsize = smb_size + 12 * 2 + smb_maxcnt;
- if (!(aio_ex = create_aio_ex_read(fsp, bufsize, req->mid,
- req->inbuf))) {
+ if ((aio_ex = create_aio_ex_read(fsp, bufsize, req->mid)) == NULL) {
DEBUG(10,("schedule_aio_read_and_X: malloc fail.\n"));
return False;
}
construct_reply_common((char *)req->inbuf, aio_ex->outbuf);
- set_message((char *)req->inbuf, aio_ex->outbuf, 12, 0, True);
+ set_message(aio_ex->outbuf, 12, 0, True);
SCVAL(aio_ex->outbuf,smb_vwv0,0xFF); /* Never a chained reply. */
a = &aio_ex->acb;
@@ -292,6 +281,7 @@ BOOL schedule_aio_write_and_X(connection_struct *conn,
struct aio_extra *aio_ex;
SMB_STRUCT_AIOCB *a;
size_t inbufsize, outbufsize;
+ BOOL write_through = BITSETW(req->inbuf+smb_vwv7,0);
size_t min_aio_write_size = lp_aio_write_size(SNUM(conn));
if (!min_aio_write_size || (numtowrite < min_aio_write_size)) {
@@ -359,7 +349,22 @@ BOOL schedule_aio_write_and_X(connection_struct *conn,
return False;
}
- srv_defer_sign_response(aio_ex->mid);
+ if (!write_through && !lp_syncalways(SNUM(fsp->conn))
+ && fsp->aio_write_behind) {
+ /* Lie to the client and immediately claim we finished the
+ * write. */
+ SSVAL(aio_ex->outbuf,smb_vwv2,numtowrite);
+ SSVAL(aio_ex->outbuf,smb_vwv4,(numtowrite>>16)&1);
+ show_msg(aio_ex->outbuf);
+ if (!send_smb(smbd_server_fd(),aio_ex->outbuf)) {
+ exit_server_cleanly("handle_aio_write: send_smb "
+ "failed.");
+ }
+ DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
+ "behind for file %s\n", fsp->fsp_name ));
+ } else {
+ srv_defer_sign_response(aio_ex->mid);
+ }
outstanding_aio_calls++;
DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write for file "
@@ -382,7 +387,6 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
int ret = 0;
int outsize;
char *outbuf = aio_ex->outbuf;
- char *inbuf = aio_ex->inbuf;
char *data = smb_buf(outbuf);
ssize_t nread = SMB_VFS_AIO_RETURN(aio_ex->fsp,&aio_ex->acb);
@@ -406,7 +410,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
outsize = (UNIXERROR(ERRDOS,ERRnoaccess));
ret = errno;
} else {
- outsize = set_message(inbuf,outbuf,12,nread,False);
+ outsize = set_message(outbuf,12,nread,False);
SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be * -1. */
SSVAL(outbuf,smb_vwv5,nread);
SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
@@ -419,7 +423,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
(int)aio_ex->acb.aio_nbytes, (int)nread ) );
}
- smb_setlen(inbuf,outbuf,outsize - 4);
+ smb_setlen(outbuf,outsize - 4);
show_msg(outbuf);
if (!send_smb(smbd_server_fd(),outbuf)) {
exit_server_cleanly("handle_aio_read_complete: send_smb "
@@ -444,10 +448,34 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
int ret = 0;
files_struct *fsp = aio_ex->fsp;
char *outbuf = aio_ex->outbuf;
- char *inbuf = aio_ex->inbuf;
ssize_t numtowrite = aio_ex->acb.aio_nbytes;
ssize_t nwritten = SMB_VFS_AIO_RETURN(fsp,&aio_ex->acb);
+ if (fsp->aio_write_behind) {
+ if (nwritten != numtowrite) {
+ if (nwritten == -1) {
+ DEBUG(5,("handle_aio_write_complete: "
+ "aio_write_behind failed ! File %s "
+ "is corrupt ! Error %s\n",
+ fsp->fsp_name, strerror(errno) ));
+ ret = errno;
+ } else {
+ DEBUG(0,("handle_aio_write_complete: "
+ "aio_write_behind failed ! File %s "
+ "is corrupt ! Wanted %u bytes but "
+ "only wrote %d\n", fsp->fsp_name,
+ (unsigned int)numtowrite,
+ (int)nwritten ));
+ ret = EIO;
+ }
+ } else {
+ DEBUG(10,("handle_aio_write_complete: "
+ "aio_write_behind completed for file %s\n",
+ fsp->fsp_name ));
+ }
+ return 0;
+ }
+
/* We don't need outsize or set_message here as we've already set the
fixed size length when we set up the aio call. */
@@ -590,6 +618,115 @@ int process_aio_queue(void)
}
/****************************************************************************
+ We're doing write behind and the client closed the file. Wait up to 30
+ seconds (my arbitrary choice) for the aio to complete. Return 0 if all writes
+ completed, errno to return if not.
+*****************************************************************************/
+
+#define SMB_TIME_FOR_AIO_COMPLETE_WAIT 29
+
+int wait_for_aio_completion(files_struct *fsp)
+{
+ struct aio_extra *aio_ex;
+ const SMB_STRUCT_AIOCB **aiocb_list;
+ int aio_completion_count = 0;
+ time_t start_time = time(NULL);
+ int seconds_left;
+
+ for (seconds_left = SMB_TIME_FOR_AIO_COMPLETE_WAIT;
+ seconds_left >= 0;) {
+ int err = 0;
+ int i;
+ struct timespec ts;
+
+ aio_completion_count = 0;
+ for( aio_ex = aio_list_head; aio_ex; aio_ex = aio_ex->next) {
+ if (aio_ex->fsp == fsp) {
+ aio_completion_count++;
+ }
+ }
+
+ if (!aio_completion_count) {
+ return 0;
+ }
+
+ DEBUG(3,("wait_for_aio_completion: waiting for %d aio events "
+ "to complete.\n", aio_completion_count ));
+
+ aiocb_list = SMB_MALLOC_ARRAY(const SMB_STRUCT_AIOCB *,
+ aio_completion_count);
+ if (!aiocb_list) {
+ return ENOMEM;
+ }
+
+ for( i = 0, aio_ex = aio_list_head;
+ aio_ex;
+ aio_ex = aio_ex->next) {
+ if (aio_ex->fsp == fsp) {
+ aiocb_list[i++] = &aio_ex->acb;
+ }
+ }
+
+ /* Now wait up to seconds_left for completion. */
+ ts.tv_sec = seconds_left;
+ ts.tv_nsec = 0;
+
+ DEBUG(10,("wait_for_aio_completion: %d events, doing a wait "
+ "of %d seconds.\n",
+ aio_completion_count, seconds_left ));
+
+ err = SMB_VFS_AIO_SUSPEND(fsp, aiocb_list,
+ aio_completion_count, &ts);
+
+ DEBUG(10,("wait_for_aio_completion: returned err = %d, "
+ "errno = %s\n", err, strerror(errno) ));
+
+ if (err == -1 && errno == EAGAIN) {
+ DEBUG(0,("wait_for_aio_completion: aio_suspend timed "
+ "out waiting for %d events after a wait of "
+ "%d seconds\n", aio_completion_count,
+ seconds_left));
+ /* Timeout. */
+ cancel_aio_by_fsp(fsp);
+ SAFE_FREE(aiocb_list);
+ return EIO;
+ }
+
+ /* One or more events might have completed - process them if
+ * so. */
+ for( i = 0; i < aio_completion_count; i++) {
+ uint16 mid = aiocb_list[i]->aio_sigevent.sigev_value.sival_int;
+
+ aio_ex = find_aio_ex(mid);
+
+ if (!aio_ex) {
+ DEBUG(0, ("wait_for_aio_completion: mid %u "
+ "doesn't match an aio record\n",
+ (unsigned int)mid ));
+ continue;
+ }
+
+ if (!handle_aio_completed(aio_ex, &err)) {
+ continue;
+ }
+ delete_aio_ex(aio_ex);
+ }
+
+ SAFE_FREE(aiocb_list);
+ seconds_left = SMB_TIME_FOR_AIO_COMPLETE_WAIT
+ - (time(NULL) - start_time);
+ }
+
+ /* We timed out - we don't know why. Return ret if already an error,
+ * else EIO. */
+ DEBUG(10,("wait_for_aio_completion: aio_suspend timed out waiting "
+ "for %d events\n",
+ aio_completion_count));
+
+ return EIO;
+}
+
+/****************************************************************************
Cancel any outstanding aio requests. The client doesn't care about the reply.
*****************************************************************************/
@@ -645,4 +782,8 @@ void cancel_aio_by_fsp(files_struct *fsp)
{
}
+BOOL wait_for_aio_completion(files_struct *fsp)
+{
+ return True;
+}
#endif
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index aee1c92f7b..ae45aaa6da 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -345,16 +345,28 @@ static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_
NTSTATUS status = NT_STATUS_OK;
NTSTATUS saved_status1 = NT_STATUS_OK;
NTSTATUS saved_status2 = NT_STATUS_OK;
+ NTSTATUS saved_status3 = NT_STATUS_OK;
connection_struct *conn = fsp->conn;
- cancel_aio_by_fsp(fsp);
+ if (fsp->aio_write_behind) {
+ /*
+ * If we're finishing write behind on a close we can get a write
+ * error here, we must remember this.
+ */
+ int ret = wait_for_aio_completion(fsp);
+ if (ret) {
+ saved_status1 = map_nt_error_from_unix(ret);
+ }
+ } else {
+ cancel_aio_by_fsp(fsp);
+ }
/*
* If we're flushing on a close we can get a write
* error here, we must remember this.
*/
- saved_status1 = close_filestruct(fsp);
+ saved_status2 = close_filestruct(fsp);
if (fsp->print_file) {
print_fsp_end(fsp, close_type);
@@ -368,7 +380,7 @@ static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_
if (fsp->fh->ref_count == 1) {
/* Should we return on error here... ? */
- saved_status2 = close_remove_share_mode(fsp, close_type);
+ saved_status3 = close_remove_share_mode(fsp, close_type);
}
if(fsp->oplock_type) {
@@ -399,6 +411,8 @@ static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_
status = saved_status1;
} else if (!NT_STATUS_IS_OK(saved_status2)) {
status = saved_status2;
+ } else if (!NT_STATUS_IS_OK(saved_status3)) {
+ status = saved_status3;
}
}
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index f9befb84d2..50a71edf9d 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -285,6 +285,7 @@ void conn_free_internal(connection_struct *conn)
free_namearray(conn->veto_list);
free_namearray(conn->hide_list);
free_namearray(conn->veto_oplock_list);
+ free_namearray(conn->aio_write_behind_list);
string_free(&conn->user);
string_free(&conn->dirpath);
diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c
index 4b807f7b90..65b7c352c5 100644
--- a/source3/smbd/connection.c
+++ b/source3/smbd/connection.c
@@ -83,19 +83,9 @@ static int count_fn(struct db_record *rec,
}
return 0;
}
-
- if (cs->name) {
- /* We are counting all the connections to a given share. */
- if (strequal(crec->servicename, cs->name)) {
- cs->curr_connections++;
- }
- } else {
- /* We are counting all the connections. Static registrations
- * like the lpq backgroud process and the smbd daemon process
- * have a cnum of -1, so won't be counted here.
- */
+
+ if (strequal(crec->servicename, cs->name))
cs->curr_connections++;
- }
return 0;
}
@@ -121,29 +111,13 @@ int count_current_connections( const char *sharename, BOOL clear )
if (connections_forall(count_fn, &cs) == -1) {
DEBUG(0,("count_current_connections: traverse of "
"connections.tdb failed\n"));
- DEBUGADD(0, ("count_current_connections: connection count of %d might not be accurate",
- cs.curr_connections));
+ return False;
}
- /* If the traverse failed part-way through, we at least return
- * as many connections as we had already counted. If it failed
- * right at the start, we will return 0, which is about all we
- * can do anywway.
- */
-
return cs.curr_connections;
}
/****************************************************************************
- Count the number of connections open across all shares.
-****************************************************************************/
-
-int count_all_current_connections(void)
-{
- return count_current_connections(NULL, True /* clear stale entries */);
-}
-
-/****************************************************************************
Claim an entry in the connections database.
****************************************************************************/
diff --git a/source3/smbd/error.c b/source3/smbd/error.c
index 143417dce3..6cb63f0c49 100644
--- a/source3/smbd/error.c
+++ b/source3/smbd/error.c
@@ -28,7 +28,7 @@ extern uint32 global_client_caps;
Create an error packet from errno.
****************************************************************************/
-int unix_error_packet(const char *inbuf,char *outbuf,int def_class,uint32 def_code, NTSTATUS def_status, int line, const char *file)
+int unix_error_packet(char *outbuf,int def_class,uint32 def_code, NTSTATUS def_status, int line, const char *file)
{
int eclass=def_class;
int ecode=def_code;
@@ -49,7 +49,7 @@ int unix_error_packet(const char *inbuf,char *outbuf,int def_class,uint32 def_co
}
}
- return error_packet(inbuf,outbuf,eclass,ecode,ntstatus,line,file);
+ return error_packet(outbuf,eclass,ecode,ntstatus,line,file);
}
BOOL use_nt_status(void)
@@ -109,9 +109,9 @@ void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatu
}
}
-int error_packet(const char *inbuf, char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
+int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
{
- int outsize = set_message(inbuf,outbuf,0,0,True);
+ int outsize = set_message(outbuf,0,0,True);
error_packet_set(outbuf, eclass, ecode, ntstatus, line, file);
return outsize;
}
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index f3740da328..179963dae9 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -558,6 +558,7 @@ NTSTATUS dup_file_fsp(files_struct *fsp,
dup_fsp->modified = fsp->modified;
dup_fsp->is_directory = fsp->is_directory;
dup_fsp->is_stat = fsp->is_stat;
+ dup_fsp->aio_write_behind = fsp->aio_write_behind;
string_set(&dup_fsp->fsp_name,fsp->fsp_name);
*result = dup_fsp;
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index da80c25407..b8c5085b41 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -131,11 +131,10 @@ static BOOL notify_marshall_changes(int num_changes,
static void change_notify_reply_packet(const uint8 *request_buf,
NTSTATUS error_code)
{
- const char *inbuf = (char *)request_buf;
char outbuf[smb_size+38];
memset(outbuf, '\0', sizeof(outbuf));
- construct_reply_common(inbuf, outbuf);
+ construct_reply_common((char *)request_buf, outbuf);
ERROR_NT(error_code);
@@ -143,7 +142,7 @@ static void change_notify_reply_packet(const uint8 *request_buf,
* Seems NT needs a transact command with an error code
* in it. This is a longer packet than a simple error.
*/
- set_message(inbuf,outbuf,18,0,False);
+ set_message(outbuf,18,0,False);
show_msg(outbuf);
if (!send_smb(smbd_server_fd(),outbuf))
@@ -187,7 +186,7 @@ void change_notify_reply(const uint8 *request_buf, uint32 max_param,
* We're only interested in the header fields here
*/
- smb_setlen(NULL, (char *)tmp_request, smb_size);
+ smb_setlen((char *)tmp_request, smb_size);
SCVAL(tmp_request, smb_wct, 0);
init_smb_request(req, tmp_request);
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index c2d7807158..fbc6f9ab64 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -387,6 +387,10 @@ static NTSTATUS open_file(files_struct *fsp,
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = False;
fsp->is_stat = False;
+ if (conn->aio_write_behind_list &&
+ is_in_path(path, conn->aio_write_behind_list, conn->case_sensitive)) {
+ fsp->aio_write_behind = True;
+ }
string_set(&fsp->fsp_name, path);
fsp->wcp = NULL; /* Write cache pointer. */
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index a5f74b89d0..9ac9d76284 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -253,7 +253,7 @@ static char *new_break_smb_message(TALLOC_CTX *mem_ctx,
}
memset(result,'\0',smb_size);
- set_message(NULL,result,8,0,True);
+ set_message(result,8,0,True);
SCVAL(result,smb_com,SMBlockingX);
SSVAL(result,smb_tid,fsp->conn->cnum);
SSVAL(result,smb_pid,0xFFFF);
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 9906bfb45b..da43a29767 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -291,7 +291,7 @@ void reply_pipe_read_and_X(struct smb_request *req)
return;
}
- set_message(NULL, (char *)req->outbuf, 12, nread, False);
+ set_message((char *)req->outbuf, 12, nread, False);
SSVAL(req->outbuf,smb_vwv5,nread);
SSVAL(req->outbuf,smb_vwv6,smb_offset(data,req->outbuf));
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 29b942de81..7faf26af25 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -91,8 +91,8 @@ void init_smb_request(struct smb_request *req, const uint8 *inbuf)
static struct pending_message_list *deferred_open_queue;
/****************************************************************************
- Function to push a message onto the tail of a linked list of smb messages
- ready for processing.
+ Function to push a message onto the tail of a linked list of smb messages ready
+ for processing.
****************************************************************************/
static BOOL push_queued_message(struct smb_request *req,
@@ -148,7 +148,7 @@ void remove_deferred_open_smb_message(uint16 mid)
for (pml = deferred_open_queue; pml; pml = pml->next) {
if (mid == SVAL(pml->buf.data,smb_mid)) {
- DEBUG(10,("remove_deferred_open_smb_message: "
+ DEBUG(10,("remove_sharing_violation_open_smb_message: "
"deleting mid %u len %u\n",
(unsigned int)mid,
(unsigned int)pml->buf.length ));
@@ -171,11 +171,11 @@ void schedule_deferred_open_smb_message(uint16 mid)
for (pml = deferred_open_queue; pml; pml = pml->next) {
uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
- DEBUG(10, ("schedule_deferred_open_smb_message: [%d] "
- "msg_mid = %u\n", i++, (unsigned int)msg_mid ));
+ DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
+ (unsigned int)msg_mid ));
if (mid == msg_mid) {
- DEBUG(10, ("schedule_deferred_open_smb_message: "
- "scheduling mid %u\n", mid));
+ DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
+ mid ));
pml->end_time.tv_sec = 0;
pml->end_time.tv_usec = 0;
DLIST_PROMOTE(deferred_open_queue, pml);
@@ -183,8 +183,8 @@ void schedule_deferred_open_smb_message(uint16 mid)
}
}
- DEBUG(10, ("schedule_deferred_open_smb_message: failed to find "
- "message mid %u\n", mid ));
+ DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
+ mid ));
}
/****************************************************************************
@@ -932,8 +932,7 @@ void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
}
construct_reply_common((char *)req->inbuf, (char *)req->outbuf);
- set_message((char *)req->inbuf, (char *)req->outbuf,
- num_words, num_bytes, False);
+ set_message((char *)req->outbuf, num_words, num_bytes, False);
/*
* Zero out the word area, the caller has to take care of the bcc area
* himself
@@ -1226,8 +1225,8 @@ void remove_from_common_flags2(uint32 v)
void construct_reply_common(const char *inbuf, char *outbuf)
{
- set_message(inbuf,outbuf,0,0,False);
-
+ set_message(outbuf,0,0,False);
+
SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
SIVAL(outbuf,smb_rcls,0);
SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
@@ -1341,7 +1340,7 @@ void chain_reply(struct smb_request *req)
}
/* And set it in the header. */
- smb_setlen(inbuf, inbuf2, new_size - 4);
+ smb_setlen(inbuf2, new_size - 4);
DEBUG(3,("Chained message\n"));
show_msg(inbuf2);
@@ -1428,7 +1427,7 @@ void chain_reply(struct smb_request *req)
memset(outbuf + outsize, 0, outsize_padded - outsize);
}
- smb_setlen(NULL, outbuf, outsize2 + chain_size - 4);
+ smb_setlen(outbuf, outsize2 + chain_size - 4);
/*
* restore the saved data, being careful not to overwrite any data
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index e27272f0dd..7c44216aea 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -402,7 +402,7 @@ void reply_special(char *inbuf)
memset(outbuf, '\0', sizeof(outbuf));
- smb_setlen(inbuf,outbuf,0);
+ smb_setlen(outbuf,0);
switch (msg_type) {
case 0x81: /* session request */
@@ -1645,8 +1645,8 @@ void reply_open(connection_struct *conn, struct smb_request *req)
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
- END_PROFILE(SMBopen);
/* We have re-scheduled this call. */
+ END_PROFILE(SMBopen);
return;
}
reply_openerror(req, status);
@@ -2040,7 +2040,7 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
/* We have re-scheduled this call. */
return;
}
- reply_nterror(req, status);
+ reply_openerror(req, status);
return;
}
@@ -3017,7 +3017,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
return;
}
- set_message(NULL, (char *)req->outbuf, 5, nread+3, False);
+ set_message((char *)req->outbuf, 5, nread+3, False);
SSVAL(req->outbuf,smb_vwv0,nread);
SSVAL(req->outbuf,smb_vwv5,nread+3);
@@ -3104,7 +3104,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
return;
}
- set_message(NULL, (char *)req->outbuf, 5, nread+3, False);
+ set_message((char *)req->outbuf, 5, nread+3, False);
SSVAL(req->outbuf,smb_vwv0,nread);
SSVAL(req->outbuf,smb_vwv5,nread+3);
@@ -3122,14 +3122,12 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
Setup readX header.
****************************************************************************/
-static int setup_readX_header(const uint8 *inbuf, uint8 *outbuf,
- size_t smb_maxcnt)
+static int setup_readX_header(char *outbuf, size_t smb_maxcnt)
{
int outsize;
char *data;
- outsize = set_message((char *)inbuf, (char *)outbuf,12,smb_maxcnt,
- False);
+ outsize = set_message(outbuf,12,smb_maxcnt,False);
data = smb_buf(outbuf);
memset(outbuf+smb_vwv0,'\0',24); /* valgrind init. */
@@ -3192,7 +3190,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
header = data_blob_const(headerbuf, sizeof(headerbuf));
construct_reply_common((char *)req->inbuf, (char *)headerbuf);
- setup_readX_header(req->inbuf, headerbuf, smb_maxcnt);
+ setup_readX_header((char *)headerbuf, smb_maxcnt);
if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, smb_maxcnt)) == -1) {
/* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
@@ -3243,7 +3241,7 @@ normal_read:
uint8 headerbuf[smb_size + 2*12];
construct_reply_common((char *)req->inbuf, (char *)headerbuf);
- setup_readX_header(req->inbuf, headerbuf, smb_maxcnt);
+ setup_readX_header((char *)headerbuf, smb_maxcnt);
/* Send out the header. */
if (write_data(smbd_server_fd(), (char *)headerbuf,
@@ -3270,7 +3268,7 @@ normal_read:
return;
}
- setup_readX_header(req->inbuf, req->outbuf, nread);
+ setup_readX_header((char *)req->outbuf, nread);
DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
@@ -3334,8 +3332,8 @@ void reply_read_and_X(connection_struct *conn, struct smb_request *req)
END_PROFILE(SMBreadX);
return;
}
- /* We currently don't do this on signed or sealed data. */
- if (srv_is_signing_active() || srv_encryption_on()) {
+ /* We currently don't do this on signed data. */
+ if (srv_is_signing_active()) {
reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
END_PROFILE(SMBreadX);
return;
@@ -3526,7 +3524,7 @@ void reply_writebraw(connection_struct *conn, struct smb_request *req)
* it to send more bytes */
memcpy(buf, req->inbuf, smb_size);
- outsize = set_message(NULL,buf,
+ outsize = set_message(buf,
Protocol>PROTOCOL_COREPLUS?1:0,0,True);
SCVAL(buf,smb_com,SMBwritebraw);
SSVALS(buf,smb_vwv0,0xFFFF);
diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c
deleted file mode 100644
index 0276e34002..0000000000
--- a/source3/smbd/seal.c
+++ /dev/null
@@ -1,703 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB Transport encryption (sealing) code - server code.
- Copyright (C) Jeremy Allison 2007.
-
- 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
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-
-/******************************************************************************
- Server side encryption.
-******************************************************************************/
-
-/******************************************************************************
- Global server state.
-******************************************************************************/
-
-struct smb_srv_trans_enc_ctx {
- struct smb_trans_enc_state *es;
- AUTH_NTLMSSP_STATE *auth_ntlmssp_state; /* Must be kept in sync with pointer in ec->ntlmssp_state. */
-};
-
-static struct smb_srv_trans_enc_ctx *partial_srv_trans_enc_ctx;
-static struct smb_srv_trans_enc_ctx *srv_trans_enc_ctx;
-
-/******************************************************************************
- Is server encryption on ?
-******************************************************************************/
-
-BOOL srv_encryption_on(void)
-{
- if (srv_trans_enc_ctx) {
- return common_encryption_on(srv_trans_enc_ctx->es);
- }
- return False;
-}
-
-/******************************************************************************
- Create an auth_ntlmssp_state and ensure pointer copy is correct.
-******************************************************************************/
-
-static NTSTATUS make_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
-{
- NTSTATUS status = auth_ntlmssp_start(&ec->auth_ntlmssp_state);
- if (!NT_STATUS_IS_OK(status)) {
- return nt_status_squash(status);
- }
-
- /*
- * We must remember to update the pointer copy for the common
- * functions after any auth_ntlmssp_start/auth_ntlmssp_end.
- */
- ec->es->s.ntlmssp_state = ec->auth_ntlmssp_state->ntlmssp_state;
- return status;
-}
-
-/******************************************************************************
- Destroy an auth_ntlmssp_state and ensure pointer copy is correct.
-******************************************************************************/
-
-static void destroy_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
-{
- /*
- * We must remember to update the pointer copy for the common
- * functions after any auth_ntlmssp_start/auth_ntlmssp_end.
- */
-
- if (ec->auth_ntlmssp_state) {
- auth_ntlmssp_end(&ec->auth_ntlmssp_state);
- /* The auth_ntlmssp_end killed this already. */
- ec->es->s.ntlmssp_state = NULL;
- }
-}
-
-#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
-
-/******************************************************************************
- Import a name.
-******************************************************************************/
-
-static NTSTATUS get_srv_gss_creds(const char *service,
- const char *name,
- gss_cred_usage_t cred_type,
- gss_cred_id_t *p_srv_cred)
-{
- OM_uint32 ret;
- OM_uint32 min;
- gss_name_t srv_name;
- gss_buffer_desc input_name;
- char *host_princ_s = NULL;
- NTSTATUS status = NT_STATUS_OK;
-
- gss_OID_desc nt_hostbased_service =
- {10, CONST_DISCARD(char *,"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")};
-
- asprintf(&host_princ_s, "%s@%s", service, name);
- if (host_princ_s == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- input_name.value = host_princ_s;
- input_name.length = strlen(host_princ_s) + 1;
-
- ret = gss_import_name(&min,
- &input_name,
- &nt_hostbased_service,
- &srv_name);
-
- DEBUG(10,("get_srv_gss_creds: imported name %s\n",
- host_princ_s ));
-
- if (ret != GSS_S_COMPLETE) {
- SAFE_FREE(host_princ_s);
- return map_nt_error_from_gss(ret, min);
- }
-
- /*
- * We're accessing the krb5.keytab file here.
- * ensure we have permissions to do so.
- */
- become_root();
-
- ret = gss_acquire_cred(&min,
- srv_name,
- GSS_C_INDEFINITE,
- GSS_C_NULL_OID_SET,
- cred_type,
- p_srv_cred,
- NULL,
- NULL);
- unbecome_root();
-
- if (ret != GSS_S_COMPLETE) {
- ADS_STATUS adss = ADS_ERROR_GSS(ret, min);
- DEBUG(10,("get_srv_gss_creds: gss_acquire_cred failed with %s\n",
- ads_errstr(adss)));
- status = map_nt_error_from_gss(ret, min);
- }
-
- SAFE_FREE(host_princ_s);
- gss_release_name(&min, &srv_name);
- return status;
-}
-
-/******************************************************************************
- Create a gss state.
- Try and get the cifs/server@realm principal first, then fall back to
- host/server@realm.
-******************************************************************************/
-
-static NTSTATUS make_auth_gss(struct smb_srv_trans_enc_ctx *ec)
-{
- NTSTATUS status;
- gss_cred_id_t srv_cred;
- fstring fqdn;
-
- name_to_fqdn(fqdn, global_myname());
- strlower_m(fqdn);
-
- status = get_srv_gss_creds("cifs", fqdn, GSS_C_ACCEPT, &srv_cred);
- if (!NT_STATUS_IS_OK(status)) {
- status = get_srv_gss_creds("host", fqdn, GSS_C_ACCEPT, &srv_cred);
- if (!NT_STATUS_IS_OK(status)) {
- return nt_status_squash(status);
- }
- }
-
- ec->es->s.gss_state = SMB_MALLOC_P(struct smb_tran_enc_state_gss);
- if (!ec->es->s.gss_state) {
- OM_uint32 min;
- gss_release_cred(&min, &srv_cred);
- return NT_STATUS_NO_MEMORY;
- }
- ZERO_STRUCTP(ec->es->s.gss_state);
- ec->es->s.gss_state->creds = srv_cred;
-
- /* No context yet. */
- ec->es->s.gss_state->gss_ctx = GSS_C_NO_CONTEXT;
-
- return NT_STATUS_OK;
-}
-#endif
-
-/******************************************************************************
- Shutdown a server encryption context.
-******************************************************************************/
-
-static void srv_free_encryption_context(struct smb_srv_trans_enc_ctx **pp_ec)
-{
- struct smb_srv_trans_enc_ctx *ec = *pp_ec;
-
- if (!ec) {
- return;
- }
-
- if (ec->es) {
- switch (ec->es->smb_enc_type) {
- case SMB_TRANS_ENC_NTLM:
- destroy_auth_ntlmssp(ec);
- break;
-#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
- case SMB_TRANS_ENC_GSS:
- break;
-#endif
- }
- common_free_encryption_state(&ec->es);
- }
-
- SAFE_FREE(ec);
- *pp_ec = NULL;
-}
-
-/******************************************************************************
- Create a server encryption context.
-******************************************************************************/
-
-static NTSTATUS make_srv_encryption_context(enum smb_trans_enc_type smb_enc_type, struct smb_srv_trans_enc_ctx **pp_ec)
-{
- struct smb_srv_trans_enc_ctx *ec;
-
- *pp_ec = NULL;
-
- ec = SMB_MALLOC_P(struct smb_srv_trans_enc_ctx);
- if (!ec) {
- return NT_STATUS_NO_MEMORY;
- }
- ZERO_STRUCTP(partial_srv_trans_enc_ctx);
- ec->es = SMB_MALLOC_P(struct smb_trans_enc_state);
- if (!ec->es) {
- SAFE_FREE(ec);
- return NT_STATUS_NO_MEMORY;
- }
- ZERO_STRUCTP(ec->es);
- ec->es->smb_enc_type = smb_enc_type;
- switch (smb_enc_type) {
- case SMB_TRANS_ENC_NTLM:
- {
- NTSTATUS status = make_auth_ntlmssp(ec);
- if (!NT_STATUS_IS_OK(status)) {
- srv_free_encryption_context(&ec);
- return status;
- }
- }
- break;
-
-#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
- case SMB_TRANS_ENC_GSS:
- /* Acquire our credentials by calling gss_acquire_cred here. */
- {
- NTSTATUS status = make_auth_gss(ec);
- if (!NT_STATUS_IS_OK(status)) {
- srv_free_encryption_context(&ec);
- return status;
- }
- }
- break;
-#endif
- default:
- srv_free_encryption_context(&ec);
- return NT_STATUS_INVALID_PARAMETER;
- }
- *pp_ec = ec;
- return NT_STATUS_OK;
-}
-
-/******************************************************************************
- Free an encryption-allocated buffer.
-******************************************************************************/
-
-void srv_free_enc_buffer(char *buf)
-{
- /* We know this is an smb buffer, and we
- * didn't malloc, only copy, for a keepalive,
- * so ignore session keepalives. */
-
- if(CVAL(buf,0) == SMBkeepalive) {
- return;
- }
-
- if (srv_trans_enc_ctx) {
- common_free_enc_buffer(srv_trans_enc_ctx->es, buf);
- }
-}
-
-/******************************************************************************
- Decrypt an incoming buffer.
-******************************************************************************/
-
-NTSTATUS srv_decrypt_buffer(char *buf)
-{
- /* Ignore session keepalives. */
- if(CVAL(buf,0) == SMBkeepalive) {
- return NT_STATUS_OK;
- }
-
- if (srv_trans_enc_ctx) {
- return common_decrypt_buffer(srv_trans_enc_ctx->es, buf);
- }
-
- return NT_STATUS_OK;
-}
-
-/******************************************************************************
- Encrypt an outgoing buffer. Return the encrypted pointer in buf_out.
-******************************************************************************/
-
-NTSTATUS srv_encrypt_buffer(char *buf, char **buf_out)
-{
- *buf_out = buf;
-
- /* Ignore session keepalives. */
- if(CVAL(buf,0) == SMBkeepalive) {
- return NT_STATUS_OK;
- }
-
- if (srv_trans_enc_ctx) {
- return common_encrypt_buffer(srv_trans_enc_ctx->es, buf, buf_out);
- }
- /* Not encrypting. */
- return NT_STATUS_OK;
-}
-
-/******************************************************************************
- Do the gss encryption negotiation. Parameters are in/out.
- Until success we do everything on the partial enc ctx.
-******************************************************************************/
-
-#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
-static NTSTATUS srv_enc_spnego_gss_negotiate(unsigned char **ppdata, size_t *p_data_size, DATA_BLOB secblob)
-{
- OM_uint32 ret;
- OM_uint32 min;
- OM_uint32 flags = 0;
- gss_buffer_desc in_buf, out_buf;
- struct smb_tran_enc_state_gss *gss_state;
- DATA_BLOB auth_reply = data_blob_null;
- DATA_BLOB response = data_blob_null;
- NTSTATUS status;
-
- if (!partial_srv_trans_enc_ctx) {
- status = make_srv_encryption_context(SMB_TRANS_ENC_GSS, &partial_srv_trans_enc_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- }
-
- gss_state = partial_srv_trans_enc_ctx->es->s.gss_state;
-
- in_buf.value = secblob.data;
- in_buf.length = secblob.length;
-
- out_buf.value = NULL;
- out_buf.length = 0;
-
- become_root();
-
- ret = gss_accept_sec_context(&min,
- &gss_state->gss_ctx,
- gss_state->creds,
- &in_buf,
- GSS_C_NO_CHANNEL_BINDINGS,
- NULL,
- NULL, /* Ignore oids. */
- &out_buf, /* To return. */
- &flags,
- NULL, /* Ingore time. */
- NULL); /* Ignore delegated creds. */
- unbecome_root();
-
- status = gss_err_to_ntstatus(ret, min);
- if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) {
- return status;
- }
-
- /* Ensure we've got sign+seal available. */
- if (ret == GSS_S_COMPLETE) {
- if ((flags & (GSS_C_INTEG_FLAG|GSS_C_CONF_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG)) !=
- (GSS_C_INTEG_FLAG|GSS_C_CONF_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG)) {
- DEBUG(0,("srv_enc_spnego_gss_negotiate: quality of service not good enough "
- "for SMB sealing.\n"));
- gss_release_buffer(&min, &out_buf);
- return NT_STATUS_ACCESS_DENIED;
- }
- }
-
- auth_reply = data_blob(out_buf.value, out_buf.length);
- gss_release_buffer(&min, &out_buf);
-
- /* Wrap in SPNEGO. */
- response = spnego_gen_auth_response(&auth_reply, status, OID_KERBEROS5);
- data_blob_free(&auth_reply);
-
- SAFE_FREE(*ppdata);
- *ppdata = response.data;
- *p_data_size = response.length;
-
- return status;
-}
-#endif
-
-/******************************************************************************
- Do the NTLM SPNEGO (or raw) encryption negotiation. Parameters are in/out.
- Until success we do everything on the partial enc ctx.
-******************************************************************************/
-
-static NTSTATUS srv_enc_ntlm_negotiate(unsigned char **ppdata, size_t *p_data_size, DATA_BLOB secblob, BOOL spnego_wrap)
-{
- NTSTATUS status;
- DATA_BLOB chal = data_blob_null;
- DATA_BLOB response = data_blob_null;
-
- status = make_srv_encryption_context(SMB_TRANS_ENC_NTLM, &partial_srv_trans_enc_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, secblob, &chal);
-
- /* status here should be NT_STATUS_MORE_PROCESSING_REQUIRED
- * for success ... */
-
- if (spnego_wrap) {
- response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);
- data_blob_free(&chal);
- } else {
- /* Return the raw blob. */
- response = chal;
- }
-
- SAFE_FREE(*ppdata);
- *ppdata = response.data;
- *p_data_size = response.length;
- return status;
-}
-
-/******************************************************************************
- Do the SPNEGO encryption negotiation. Parameters are in/out.
- Based off code in smbd/sesssionsetup.c
- Until success we do everything on the partial enc ctx.
-******************************************************************************/
-
-static NTSTATUS srv_enc_spnego_negotiate(connection_struct *conn,
- unsigned char **ppdata,
- size_t *p_data_size,
- unsigned char **pparam,
- size_t *p_param_size)
-{
- NTSTATUS status;
- DATA_BLOB blob = data_blob_null;
- DATA_BLOB secblob = data_blob_null;
- BOOL got_kerberos_mechanism = False;
-
- blob = data_blob_const(*ppdata, *p_data_size);
-
- status = parse_spnego_mechanisms(blob, &secblob, &got_kerberos_mechanism);
- if (!NT_STATUS_IS_OK(status)) {
- return nt_status_squash(status);
- }
-
- /* We should have no partial context at this point. */
-
- srv_free_encryption_context(&partial_srv_trans_enc_ctx);
-
-#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
- if (got_kerberos_mechanism && lp_use_kerberos_keytab() ) {
- status = srv_enc_spnego_gss_negotiate(ppdata, p_data_size, secblob);
- } else
-#endif
- {
- status = srv_enc_ntlm_negotiate(ppdata, p_data_size, secblob, True);
- }
-
- data_blob_free(&secblob);
-
- if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
- srv_free_encryption_context(&partial_srv_trans_enc_ctx);
- return nt_status_squash(status);
- }
-
- if (NT_STATUS_IS_OK(status)) {
- /* Return the context we're using for this encryption state. */
- if (!(*pparam = SMB_MALLOC_ARRAY(unsigned char, 2))) {
- return NT_STATUS_NO_MEMORY;
- }
- SSVAL(*pparam,0,partial_srv_trans_enc_ctx->es->enc_ctx_num);
- *p_param_size = 2;
- }
-
- return status;
-}
-
-/******************************************************************************
- Complete a SPNEGO encryption negotiation. Parameters are in/out.
- We only get this for a NTLM auth second stage.
-******************************************************************************/
-
-static NTSTATUS srv_enc_spnego_ntlm_auth(connection_struct *conn,
- unsigned char **ppdata,
- size_t *p_data_size,
- unsigned char **pparam,
- size_t *p_param_size)
-{
- NTSTATUS status;
- DATA_BLOB blob = data_blob_null;
- DATA_BLOB auth = data_blob_null;
- DATA_BLOB auth_reply = data_blob_null;
- DATA_BLOB response = data_blob_null;
- struct smb_srv_trans_enc_ctx *ec = partial_srv_trans_enc_ctx;
-
- /* We must have a partial context here. */
-
- if (!ec || !ec->es || ec->auth_ntlmssp_state == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
- srv_free_encryption_context(&partial_srv_trans_enc_ctx);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- blob = data_blob_const(*ppdata, *p_data_size);
- if (!spnego_parse_auth(blob, &auth)) {
- srv_free_encryption_context(&partial_srv_trans_enc_ctx);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- status = auth_ntlmssp_update(ec->auth_ntlmssp_state, auth, &auth_reply);
- data_blob_free(&auth);
-
- response = spnego_gen_auth_response(&auth_reply, status, OID_NTLMSSP);
- data_blob_free(&auth_reply);
-
- if (NT_STATUS_IS_OK(status)) {
- /* Return the context we're using for this encryption state. */
- if (!(*pparam = SMB_MALLOC_ARRAY(unsigned char, 2))) {
- return NT_STATUS_NO_MEMORY;
- }
- SSVAL(*pparam,0,ec->es->enc_ctx_num);
- *p_param_size = 2;
- }
-
- SAFE_FREE(*ppdata);
- *ppdata = response.data;
- *p_data_size = response.length;
- return status;
-}
-
-/******************************************************************************
- Raw NTLM encryption negotiation. Parameters are in/out.
- This function does both steps.
-******************************************************************************/
-
-static NTSTATUS srv_enc_raw_ntlm_auth(connection_struct *conn,
- unsigned char **ppdata,
- size_t *p_data_size,
- unsigned char **pparam,
- size_t *p_param_size)
-{
- NTSTATUS status;
- DATA_BLOB blob = data_blob_const(*ppdata, *p_data_size);
- DATA_BLOB response = data_blob_null;
- struct smb_srv_trans_enc_ctx *ec;
-
- if (!partial_srv_trans_enc_ctx) {
- /* This is the initial step. */
- status = srv_enc_ntlm_negotiate(ppdata, p_data_size, blob, False);
- if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
- srv_free_encryption_context(&partial_srv_trans_enc_ctx);
- return nt_status_squash(status);
- }
- return status;
- }
-
- ec = partial_srv_trans_enc_ctx;
- if (!ec || !ec->es || ec->auth_ntlmssp_state == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
- srv_free_encryption_context(&partial_srv_trans_enc_ctx);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* Second step. */
- status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, blob, &response);
-
- if (NT_STATUS_IS_OK(status)) {
- /* Return the context we're using for this encryption state. */
- if (!(*pparam = SMB_MALLOC_ARRAY(unsigned char, 2))) {
- return NT_STATUS_NO_MEMORY;
- }
- SSVAL(*pparam,0,ec->es->enc_ctx_num);
- *p_param_size = 2;
- }
-
- /* Return the raw blob. */
- SAFE_FREE(*ppdata);
- *ppdata = response.data;
- *p_data_size = response.length;
- return status;
-}
-
-/******************************************************************************
- Do the SPNEGO encryption negotiation. Parameters are in/out.
-******************************************************************************/
-
-NTSTATUS srv_request_encryption_setup(connection_struct *conn,
- unsigned char **ppdata,
- size_t *p_data_size,
- unsigned char **pparam,
- size_t *p_param_size)
-{
- unsigned char *pdata = *ppdata;
-
- SAFE_FREE(*pparam);
- *p_param_size = 0;
-
- if (*p_data_size < 1) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (pdata[0] == ASN1_APPLICATION(0)) {
- /* its a negTokenTarg packet */
- return srv_enc_spnego_negotiate(conn, ppdata, p_data_size, pparam, p_param_size);
- }
-
- if (pdata[0] == ASN1_CONTEXT(1)) {
- /* It's an auth packet */
- return srv_enc_spnego_ntlm_auth(conn, ppdata, p_data_size, pparam, p_param_size);
- }
-
- /* Maybe it's a raw unwrapped auth ? */
- if (*p_data_size < 7) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (strncmp((char *)pdata, "NTLMSSP", 7) == 0) {
- return srv_enc_raw_ntlm_auth(conn, ppdata, p_data_size, pparam, p_param_size);
- }
-
- DEBUG(1,("srv_request_encryption_setup: Unknown packet\n"));
-
- return NT_STATUS_LOGON_FAILURE;
-}
-
-/******************************************************************************
- Negotiation was successful - turn on server-side encryption.
-******************************************************************************/
-
-static NTSTATUS check_enc_good(struct smb_srv_trans_enc_ctx *ec)
-{
- if (!ec || !ec->es) {
- return NT_STATUS_LOGON_FAILURE;
- }
-
- if (ec->es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
- if ((ec->es->s.ntlmssp_state->neg_flags & (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL)) !=
- (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
- }
- /* Todo - check gssapi case. */
-
- return NT_STATUS_OK;
-}
-
-/******************************************************************************
- Negotiation was successful - turn on server-side encryption.
-******************************************************************************/
-
-NTSTATUS srv_encryption_start(connection_struct *conn)
-{
- NTSTATUS status;
-
- /* Check that we are really doing sign+seal. */
- status = check_enc_good(partial_srv_trans_enc_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- /* Throw away the context we're using currently (if any). */
- srv_free_encryption_context(&srv_trans_enc_ctx);
-
- /* Steal the partial pointer. Deliberate shallow copy. */
- srv_trans_enc_ctx = partial_srv_trans_enc_ctx;
- srv_trans_enc_ctx->es->enc_on = True;
-
- partial_srv_trans_enc_ctx = NULL;
- return NT_STATUS_OK;
-}
-
-/******************************************************************************
- Shutdown all server contexts.
-******************************************************************************/
-
-void server_encryption_shutdown(void)
-{
- srv_free_encryption_context(&partial_srv_trans_enc_ctx);
- srv_free_encryption_context(&srv_trans_enc_ctx);
-}
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 72eeb7ee6a..0f47a550e9 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -4,7 +4,6 @@
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Martin Pool 2002
Copyright (C) Jelmer Vernooij 2002-2003
- Copyright (C) James Peach 2007
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
@@ -294,33 +293,25 @@ static BOOL allowable_number_of_smbd_processes(void)
}
/****************************************************************************
- Are we idle enough that we could safely exit?
-****************************************************************************/
-
-static BOOL smbd_is_idle(void)
-{
- /* Currently we define "idle" as having no client connections. */
- return count_all_current_connections() == 0;
-}
-
-/****************************************************************************
Open the socket communication.
****************************************************************************/
-static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const char *smb_ports)
+static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ports)
{
+ int num_interfaces = iface_count();
int num_sockets = 0;
int fd_listenset[FD_SETSIZE];
fd_set listen_set;
int s;
int maxfd = 0;
int i;
- struct timeval idle_timeout = timeval_zero();
+ char *ports;
- if (server_mode == SERVER_MODE_INETD) {
+ if (!is_daemon) {
return open_sockets_inetd();
}
+
#ifdef HAVE_ATEXIT
{
static int atexit_set;
@@ -333,21 +324,116 @@ static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const char *smb_
/* Stop zombies */
CatchSignal(SIGCLD, sig_cld);
-
+
FD_ZERO(&listen_set);
- /* At this point, it doesn't matter what daemon mode we are in, we
- * need some sockets to listen on.
- */
- num_sockets = smbd_sockinit(smb_ports, fd_listenset, &idle_timeout);
- if (num_sockets == 0) {
- return False;
+ /* use a reasonable default set of ports - listing on 445 and 139 */
+ if (!smb_ports) {
+ ports = lp_smb_ports();
+ if (!ports || !*ports) {
+ ports = smb_xstrdup(SMB_PORTS);
+ } else {
+ ports = smb_xstrdup(ports);
+ }
+ } else {
+ ports = smb_xstrdup(smb_ports);
}
- for (i = 0; i < num_sockets; ++i) {
- FD_SET(fd_listenset[i], &listen_set);
- maxfd = MAX(maxfd, fd_listenset[i]);
- }
+ 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.
+ */
+
+ /* 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;
+ const char *ptr;
+
+ if(ifip == NULL) {
+ DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
+ continue;
+ }
+
+ for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
+ unsigned port = atoi(tok);
+ if (port == 0 || port > 0xffff) {
+ 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);
+
+ /* Set server socket to non-blocking for the accept. */
+ set_blocking(s,False);
+
+ if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
+ DEBUG(0,("listen: %s\n",strerror(errno)));
+ close(s);
+ return False;
+ }
+ FD_SET(s,&listen_set);
+ maxfd = MAX( maxfd, s);
+
+ num_sockets++;
+ if (num_sockets >= FD_SETSIZE) {
+ DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
+ return False;
+ }
+ }
+ }
+ } else {
+ /* Just bind to 0.0.0.0 - accept connections
+ from anywhere. */
+
+ fstring tok;
+ const char *ptr;
+
+ num_interfaces = 1;
+
+ for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
+ unsigned port = atoi(tok);
+ if (port == 0 || port > 0xffff) continue;
+ /* 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);
+
+ /* Set server socket to non-blocking for the accept. */
+ set_blocking(s,False);
+
+ if (listen(s, SMBD_LISTEN_BACKLOG) == -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);
+ maxfd = MAX( maxfd, s);
+
+ num_sockets++;
+
+ if (num_sockets >= FD_SETSIZE) {
+ DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
+ return False;
+ }
+ }
+ }
+
+ SAFE_FREE(ports);
/* Setup the main smbd so that we can get messages. Note that
@@ -380,7 +466,7 @@ static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const char *smb_
for each incoming connection */
DEBUG(2,("waiting for a connection\n"));
while (1) {
- struct timeval now;
+ struct timeval now, idle_timeout;
fd_set r_fds, w_fds;
int num;
@@ -396,6 +482,8 @@ static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const char *smb_
}
}
+ idle_timeout = timeval_zero();
+
memcpy((char *)&r_fds, (char *)&listen_set,
sizeof(listen_set));
FD_ZERO(&w_fds);
@@ -405,21 +493,9 @@ static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const char *smb_
&r_fds, &w_fds, &idle_timeout,
&maxfd);
- if (timeval_is_zero(&idle_timeout)) {
- num = sys_select(maxfd + 1, &r_fds, &w_fds,
- NULL, NULL);
- } else {
- num = sys_select(maxfd + 1, &r_fds, &w_fds,
- NULL, &idle_timeout);
-
- /* If the idle timeout fired and we are idle, exit
- * gracefully. We expect to be running under a process
- * controller that will restart us if necessry.
- */
- if (num == 0 && smbd_is_idle()) {
- exit_server_cleanly("idle timeout");
- }
- }
+ num = sys_select(maxfd+1,&r_fds,&w_fds,NULL,
+ timeval_is_zero(&idle_timeout) ?
+ NULL : &idle_timeout);
if (num == -1 && errno == EINTR) {
if (got_sig_term) {
@@ -436,7 +512,7 @@ static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const char *smb_
continue;
}
-
+
if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) {
continue;
}
@@ -476,13 +552,8 @@ static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const char *smb_
/* Ensure child is set to blocking mode */
set_blocking(smbd_server_fd(),True);
- /* In interactive mode, return with a connected socket.
- * Foreground and daemon modes should fork worker
- * processes.
- */
- if (server_mode == SERVER_MODE_INTERACTIVE) {
+ if (smbd_server_fd() != -1 && interactive)
return True;
- }
if (allowable_number_of_smbd_processes() &&
smbd_server_fd() != -1 &&
@@ -694,8 +765,6 @@ static void exit_server_common(enum server_exit_reason how,
locking_end();
printing_end();
- server_encryption_shutdown();
-
if (how != SERVER_EXIT_NORMAL) {
int oldlevel = DEBUGLEVEL;
@@ -804,26 +873,23 @@ extern void build_options(BOOL screen);
int main(int argc,const char *argv[])
{
/* shall I run as a daemon */
- BOOL no_process_group = False;
- BOOL log_stdout = False;
- const char *ports = NULL;
- const char *profile_level = NULL;
+ static BOOL is_daemon = False;
+ static BOOL interactive = False;
+ static BOOL Fork = True;
+ static BOOL no_process_group = False;
+ static BOOL log_stdout = False;
+ static char *ports = NULL;
+ static char *profile_level = NULL;
int opt;
poptContext pc;
BOOL print_build_options = False;
- enum smb_server_mode server_mode = SERVER_MODE_DAEMON;
-
struct poptOption long_options[] = {
POPT_AUTOHELP
- {"daemon", 'D', POPT_ARG_VAL, &server_mode, SERVER_MODE_DAEMON,
- "Become a daemon (default)" },
- {"interactive", 'i', POPT_ARG_VAL, &server_mode, SERVER_MODE_INTERACTIVE,
- "Run interactive (not a daemon)"},
- {"foreground", 'F', POPT_ARG_VAL, &server_mode, SERVER_MODE_FOREGROUND,
- "Run daemon in foreground (for daemontools, etc.)" },
- {"no-process-group", '\0', POPT_ARG_VAL, &no_process_group, True,
- "Don't create a new process group" },
+ {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" },
+ {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)"},
+ {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools, etc.)" },
+ {"no-process-group", '\0', POPT_ARG_VAL, &no_process_group, True, "Don't create a new process group" },
{"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
{"build-options", 'b', POPT_ARG_NONE, NULL, 'b', "Print build options" },
{"port", 'p', POPT_ARG_STRING, &ports, 0, "Listen on the specified ports"},
@@ -870,14 +936,16 @@ extern void build_options(BOOL screen);
set_remote_machine_name("smbd", False);
- if (server_mode == SERVER_MODE_INTERACTIVE) {
+ if (interactive) {
+ Fork = False;
log_stdout = True;
- if (DEBUGLEVEL >= 9) {
- talloc_enable_leak_report();
- }
}
- if (log_stdout && server_mode == SERVER_MODE_DAEMON) {
+ if (interactive && (DEBUGLEVEL >= 9)) {
+ talloc_enable_leak_report();
+ }
+
+ if (log_stdout && Fork) {
DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
exit(1);
}
@@ -967,19 +1035,21 @@ extern void build_options(BOOL screen);
DEBUG(3,( "loaded services\n"));
- if (is_a_socket(0)) {
- if (server_mode == SERVER_MODE_DAEMON) {
- DEBUG(0,("standard input is a socket, "
- "assuming -F option\n"));
- }
- server_mode = SERVER_MODE_INETD;
+ if (!is_daemon && !is_a_socket(0)) {
+ if (!interactive)
+ DEBUG(0,("standard input is not a socket, assuming -D option\n"));
+
+ /*
+ * Setting is_daemon here prevents us from eventually calling
+ * the open_sockets_inetd()
+ */
+
+ is_daemon = True;
}
- if (server_mode == SERVER_MODE_DAEMON) {
+ if (is_daemon && !interactive) {
DEBUG( 3, ( "Becoming a daemon.\n" ) );
- become_daemon(True, no_process_group);
- } else if (server_mode == SERVER_MODE_FOREGROUND) {
- become_daemon(False, no_process_group);
+ become_daemon(Fork, no_process_group);
}
#if HAVE_SETPGID
@@ -987,18 +1057,15 @@ extern void build_options(BOOL screen);
* If we're interactive we want to set our own process group for
* signal management.
*/
- if (server_mode == SERVER_MODE_INTERACTIVE && !no_process_group) {
+ if (interactive && !no_process_group)
setpgid( (pid_t)0, (pid_t)0);
- }
#endif
if (!directory_exist(lp_lockdir(), NULL))
mkdir(lp_lockdir(), 0755);
- if (server_mode != SERVER_MODE_INETD &&
- server_mode != SERVER_MODE_INTERACTIVE) {
+ if (is_daemon)
pidfile_create("smbd");
- }
/* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
@@ -1052,10 +1119,9 @@ extern void build_options(BOOL screen);
running as a daemon -- bad things will happen if
smbd is launched via inetd and we fork a copy of
ourselves here */
- if (server_mode != SERVER_MODE_INETD &&
- server_mode != SERVER_MODE_INTERACTIVE) {
+
+ if ( is_daemon && !interactive )
start_background_queue();
- }
/* Always attempt to initialize DMAPI. We will only use it later if
* lp_dmapi_support is set on the share, but we need a single global
@@ -1063,9 +1129,8 @@ extern void build_options(BOOL screen);
*/
dmapi_init_session();
- if (!open_sockets_smbd(server_mode, ports)) {
+ if (!open_sockets_smbd(is_daemon, interactive, ports))
exit(1);
- }
/*
* everything after this point is run after the fork()
@@ -1078,8 +1143,7 @@ extern void build_options(BOOL screen);
/* Possibly reload the services file. Only worth doing in
* daemon mode. In inetd mode, we know we only just loaded this.
*/
- if (server_mode != SERVER_MODE_INETD &&
- server_mode != SERVER_MODE_INTERACTIVE) {
+ if (is_daemon) {
reload_services(True);
}
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 4daa2924a2..1c46e3776c 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -312,14 +312,7 @@ static int load_registry_service(const char *servicename)
TALLOC_FREE(value);
}
- if (!service_ok(res)) {
- /* this is actually never reached, since
- * service_ok only returns False if the service
- * entry does not have a service name, and we _know_
- * we do have a service name here... */
- res = -1;
- }
-
+ res = 0;
error:
TALLOC_FREE(key);
@@ -409,6 +402,10 @@ int find_service(fstring service)
if (iService < 0) {
}
+ if (iService < 0) {
+ iService = load_registry_service(service);
+ }
+
/* Is it a usershare service ? */
if (iService < 0 && *lp_usershare_path()) {
/* Ensure the name is canonicalized. */
@@ -444,10 +441,6 @@ int find_service(fstring service)
}
}
- if (iService < 0) {
- iService = load_registry_service(service);
- }
-
if (iService >= 0) {
if (!VALID_SNUM(iService)) {
DEBUG(0,("Invalid snum %d for %s\n",iService, service));
@@ -789,6 +782,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
conn->veto_list = NULL;
conn->hide_list = NULL;
conn->veto_oplock_list = NULL;
+ conn->aio_write_behind_list = NULL;
string_set(&conn->dirpath,"");
string_set(&conn->user,user);
diff --git a/source3/smbd/session.c b/source3/smbd/session.c
index c7cdf41fb5..8dd321fad7 100644
--- a/source3/smbd/session.c
+++ b/source3/smbd/session.c
@@ -201,12 +201,9 @@ BOOL session_claim(user_struct *vuser)
sessionid.id_str, sessionid.id_num);
}
- TALLOC_FREE(rec);
-
vuser->session_keystr = talloc_strdup(vuser, keystr);
if (!vuser->session_keystr) {
- DEBUG(0, ("session_claim: talloc_strdup() failed for "
- "session_keystr\n"));
+ DEBUG(0, ("session_claim: talloc_strdup() failed for session_keystr\n"));
return False;
}
return True;
diff --git a/source3/smbd/sockinit.c b/source3/smbd/sockinit.c
deleted file mode 100644
index 598bbd1bda..0000000000
--- a/source3/smbd/sockinit.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) James Peach 2007
-
- 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
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "smb_launchd.h"
-
-extern pstring user_socket_options;
-
-static int init_sockets_smbd(const char *smb_ports, int listenset[FD_SETSIZE])
-{
- int num_interfaces = iface_count();
- char * ports;
- int num_sockets = 0;
- int i, s;
-
- /* use a reasonable default set of ports - listing on 445 and 139 */
- if (!smb_ports) {
- ports = lp_smb_ports();
- if (!ports || !*ports) {
- ports = smb_xstrdup(SMB_PORTS);
- } else {
- ports = smb_xstrdup(ports);
- }
- } else {
- ports = smb_xstrdup(smb_ports);
- }
-
- 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.
- */
-
- /* 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;
- const char *ptr;
-
- if(ifip == NULL) {
- DEBUG(0,("init_sockets_smbd: interface %d has "
- "NULL IP address !\n", i));
- continue;
- }
-
- for (ptr=ports; next_token(&ptr, tok, " \t,",
- sizeof(tok)); ) {
- unsigned port = atoi(tok);
- if (port == 0 || port > 0xffff) {
- continue;
- }
- s = listenset[num_sockets] =
- open_socket_in(SOCK_STREAM,
- port,
- 0,
- ifip->s_addr,
- True);
- if(s == -1)
- return 0;
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
-
- /* Set server socket to non-blocking
- * for the accept. */
- set_blocking(s,False);
-
- if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
- DEBUG(0,("listen: %s\n",
- strerror(errno)));
- close(s);
- return 0;
- }
-
- num_sockets++;
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("init_sockets_smbd: "
- "Too many sockets to bind to\n"));
- return 0;
- }
- }
- }
- } else {
- /* Just bind to 0.0.0.0 - accept connections
- from anywhere. */
-
- fstring tok;
- const char *ptr;
-
- num_interfaces = 1;
-
- for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
- unsigned port = atoi(tok);
- if (port == 0 || port > 0xffff) continue;
- /* open an incoming socket */
- s = open_socket_in(SOCK_STREAM, port, 0,
- interpret_addr(lp_socket_address()),
- True);
- if (s == -1)
- return 0;
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
-
- /* Set server socket to non-blocking for the accept. */
- set_blocking(s,False);
-
- if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
- DEBUG(0,("init_sockets_smbd: listen: %s\n",
- strerror(errno)));
- close(s);
- return 0;
- }
-
- listenset[num_sockets] = s;
- num_sockets++;
-
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("init_sockets_smbd: "
- "Too many sockets to bind to\n"));
- return 0;
- }
- }
- }
-
- SAFE_FREE(ports);
- return num_sockets;
-}
-
-static int init_sockets_launchd(const struct smb_launch_info *linfo,
- const char * smb_ports,
- int listenset[FD_SETSIZE])
-{
- int num_sockets;
- int i;
-
- /* The launchd service configuration does not have to provide sockets,
- * even though it's basically useless without it.
- */
- if (!linfo->num_sockets) {
- return init_sockets_smbd(smb_ports, listenset);
- }
-
- /* Make sure we don't get more sockets than we can handle. */
- num_sockets = MIN(FD_SETSIZE, linfo->num_sockets);
- memcpy(listenset, linfo->socket_list, num_sockets * sizeof(int));
-
- /* Get the sockets ready. This could be hoisted into
- * open_sockets_smbd(), but the order of socket operations might
- * matter for some platforms, so this approach seems less risky.
- * --jpeach
- */
- for (i = 0; i < num_sockets; ++i) {
- set_socket_options(listenset[i], "SO_KEEPALIVE");
- set_socket_options(listenset[i], user_socket_options);
-
- /* Set server socket to non-blocking for the accept. */
- set_blocking(listenset[i], False);
- }
-
- return num_sockets;
-}
-
-/* This function is responsible for opening (or retrieving) all the sockets we
- * smbd will be listening on. It should apply all the configured socket options
- * and return the number of valid sockets in listenset.
- */
-int smbd_sockinit(const char *cmdline_ports, int listenset[FD_SETSIZE],
- struct timeval *idle)
-{
- int num_sockets;
- struct smb_launch_info linfo;
-
- ZERO_STRUCTP(idle);
-
- if (smb_launchd_checkin(&linfo)) {
- /* We are running under launchd and launchd has
- * opened some sockets for us.
- */
- num_sockets = init_sockets_launchd(&linfo,
- cmdline_ports,
- listenset);
- idle->tv_sec = linfo.idle_timeout_secs;
- smb_launchd_checkout(&linfo);
- } else {
- num_sockets = init_sockets_smbd(cmdline_ports,
- listenset);
- }
-
- return num_sockets;
-}
diff --git a/source3/smbd/srvstr.c b/source3/smbd/srvstr.c
index fbcf249ffb..68e61033ae 100644
--- a/source3/smbd/srvstr.c
+++ b/source3/smbd/srvstr.c
@@ -79,7 +79,7 @@ ssize_t message_push_string(uint8 **outbuf, const char *str, int flags)
DEBUG(0, ("srvstr_push failed\n"));
return -1;
}
- set_message_bcc(NULL, (char *)tmp, smb_buflen(tmp) + result);
+ set_message_bcc((char *)tmp, smb_buflen(tmp) + result);
*outbuf = tmp;
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index ada4868bf8..7392271b48 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -2733,9 +2733,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
CIFS_UNIX_FCNTL_LOCKS_CAP|
CIFS_UNIX_EXTATTR_CAP|
CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
- /* Ensure we don't do this on signed or sealed data. */
- (srv_is_signing_active() ? 0 : CIFS_UNIX_LARGE_READ_CAP)
- )));
+ CIFS_UNIX_LARGE_READ_CAP)));
break;
case SMB_QUERY_POSIX_FS_INFO:
@@ -2986,51 +2984,6 @@ cap_low = 0x%x, cap_high = 0x%x\n",
}
break;
}
- case SMB_REQUEST_TRANSPORT_ENCRYPTION:
- {
- NTSTATUS status;
- size_t param_len = 0;
- size_t data_len = total_data;
-
- if (!lp_unix_extensions()) {
- reply_nterror(
- req, NT_STATUS_INVALID_LEVEL);
- return;
- }
-
- DEBUG( 4,("call_trans2setfsinfo: request transport encrption.\n"));
-
- status = srv_request_encryption_setup(conn,
- (unsigned char **)ppdata,
- &data_len,
- (unsigned char **)pparams,
- &param_len
- );
-
- if (!NT_STATUS_IS_OK(status)) {
- /*
- * TODO: Check
- * MORE_PROCESSING_REQUIRED, this used
- * to have special handling here.
- */
- reply_nterror(req, status);
- return;
- }
-
- send_trans2_replies(req,
- *pparams, param_len,
- *ppdata, data_len,
- max_data_bytes);
-
- if (NT_STATUS_IS_OK(status)) {
- /* Server-side transport encryption is now *on*. */
- status = srv_encryption_start(conn);
- if (!NT_STATUS_IS_OK(status)) {
- exit_server_cleanly("Failure in setting up encrypted transport");
- }
- }
- return;
- }
case SMB_FS_QUOTA_INFORMATION:
{
files_struct *fsp = NULL;
diff --git a/source3/smbd/utmp.c b/source3/smbd/utmp.c
index 7f43740754..52174c4d83 100644
--- a/source3/smbd/utmp.c
+++ b/source3/smbd/utmp.c
@@ -220,13 +220,13 @@ static void uw_pathname(pstring fname, const char *uw_name, const char *uw_defau
}
/* For u-files and non-explicit w-dir, look for "utmp dir" */
- if (strlen(dirname) == 0) {
+ if (dirname == 0 || strlen(dirname) == 0) {
pstrcpy(dirname,lp_utmpdir());
trim_char(dirname,'\0','/');
}
/* If explicit directory above, use it */
- if (strlen(dirname) != 0) {
+ if (dirname != 0 && strlen(dirname) != 0) {
pstrcpy(fname, dirname);
pstrcat(fname, "/");
pstrcat(fname, uw_name);