diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/chgpasswd.c | 19 | ||||
-rw-r--r-- | source3/smbd/lanman.c | 2 | ||||
-rw-r--r-- | source3/smbd/map_username.c | 6 | ||||
-rw-r--r-- | source3/smbd/oplock_irix.c | 2 | ||||
-rw-r--r-- | source3/smbd/password.c | 15 | ||||
-rw-r--r-- | source3/smbd/process.c | 298 | ||||
-rw-r--r-- | source3/smbd/reply.c | 21 |
7 files changed, 155 insertions, 208 deletions
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 668c8e2095..e7ab60d22f 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -239,7 +239,8 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass, static int expect(int master, char *issue, char *expected) { char buffer[1024]; - int attempts, timeout, nread, len; + int attempts, timeout, nread; + size_t len; bool match = False; for (attempts = 0; attempts < 2; attempts++) { @@ -248,7 +249,8 @@ static int expect(int master, char *issue, char *expected) DEBUG(100, ("expect: sending [%s]\n", issue)); if ((len = sys_write(master, issue, strlen(issue))) != strlen(issue)) { - DEBUG(2,("expect: (short) write returned %d\n", len )); + DEBUG(2,("expect: (short) write returned %d\n", + (int)len )); return False; } } @@ -261,9 +263,16 @@ static int expect(int master, char *issue, char *expected) nread = 0; buffer[nread] = 0; - while ((len = read_socket_with_timeout(master, buffer + nread, 1, - sizeof(buffer) - nread - 1, - timeout, NULL)) > 0) { + while (True) { + NTSTATUS status; + status = read_socket_with_timeout( + master, buffer + nread, 1, + sizeof(buffer) - nread - 1, + timeout, &len); + + if (!NT_STATUS_IS_OK(status)) { + break; + } nread += len; buffer[nread] = 0; diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 5a6df1f139..18e6bf9f7b 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -3175,7 +3175,7 @@ static bool api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, where: - usri11_name specifies the user name for which information is retireved + usri11_name specifies the user name for which information is retrieved usri11_pad aligns the next data structure element to a word boundary diff --git a/source3/smbd/map_username.c b/source3/smbd/map_username.c index 7290f70547..7536758bcb 100644 --- a/source3/smbd/map_username.c +++ b/source3/smbd/map_username.c @@ -178,7 +178,7 @@ bool map_username(fstring user) /* skip lines like 'user = ' */ - dosuserlist = str_list_make(dosname, NULL); + dosuserlist = str_list_make(talloc_tos(), dosname, NULL); if (!dosuserlist) { DEBUG(0,("Bad username map entry. Unable to build user list. Ignoring.\n")); continue; @@ -193,13 +193,13 @@ bool map_username(fstring user) fstrcpy( user, unixname ); if ( return_if_mapped ) { - str_list_free (&dosuserlist); + TALLOC_FREE(dosuserlist); x_fclose(f); return True; } } - str_list_free (&dosuserlist); + TALLOC_FREE(dosuserlist); } x_fclose(f); diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c index a4ea63bc0a..788cd04c17 100644 --- a/source3/smbd/oplock_irix.c +++ b/source3/smbd/oplock_irix.c @@ -121,7 +121,6 @@ static files_struct *irix_oplock_receive_message(fd_set *fds) DEBUG(0,("irix_oplock_receive_message: read of kernel " "notification failed. Error was %s.\n", strerror(errno) )); - set_smb_read_error(get_srv_read_error(), SMB_READ_ERROR); return NULL; } @@ -141,7 +140,6 @@ static files_struct *irix_oplock_receive_message(fd_set *fds) */ return NULL; } - set_smb_read_error(get_srv_read_error(), SMB_READ_ERROR); return NULL; } diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 85e1ccf0a7..687b67950a 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -582,7 +582,7 @@ static bool user_ok(const char *user, int snum) ret = True; if (lp_invalid_users(snum)) { - str_list_copy(&invalid, lp_invalid_users(snum)); + str_list_copy(talloc_tos(), &invalid, lp_invalid_users(snum)); if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) { @@ -595,11 +595,10 @@ static bool user_ok(const char *user, int snum) } } } - if (invalid) - str_list_free (&invalid); + TALLOC_FREE(invalid); if (ret && lp_valid_users(snum)) { - str_list_copy(&valid, lp_valid_users(snum)); + str_list_copy(talloc_tos(), &valid, lp_valid_users(snum)); if ( valid && str_list_substitute(valid, "%S", lp_servicename(snum)) ) { @@ -611,17 +610,17 @@ static bool user_ok(const char *user, int snum) } } } - if (valid) - str_list_free (&valid); + TALLOC_FREE(valid); if (ret && lp_onlyuser(snum)) { - char **user_list = str_list_make (lp_username(snum), NULL); + char **user_list = str_list_make( + talloc_tos(), lp_username(snum), NULL); if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) { ret = user_in_list(user, (const char **)user_list); } - if (user_list) str_list_free (&user_list); + TALLOC_FREE(user_list); } return(ret); diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 4672510d8d..68bec7830a 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -22,8 +22,6 @@ extern int smb_echo_count; -static enum smb_read_errors smb_read_error = SMB_READ_OK; - /* * Size of data we can send to client. Set * by the client for all protocols above CORE. @@ -43,11 +41,6 @@ extern int max_send; /* Accessor function for smb_read_error for smbd functions. */ -enum smb_read_errors *get_srv_read_error(void) -{ - return &smb_read_error; -} - /**************************************************************************** Send an smb to a fd. ****************************************************************************/ @@ -128,42 +121,20 @@ static bool valid_packet_size(size_t len) DEBUG(0,("Invalid packet length! (%lu bytes).\n", (unsigned long)len)); if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { - - /* - * Correct fix. smb_read_error may have already been - * set. Only set it here if not already set. Global - * variables still suck :-). JRA. - */ - - cond_set_smb_read_error(get_srv_read_error(), - SMB_READ_ERROR); return false; } } return true; } -static ssize_t read_packet_remainder(int fd, - char *buffer, - unsigned int timeout, - ssize_t len) +static NTSTATUS read_packet_remainder(int fd, char *buffer, + unsigned int timeout, ssize_t len) { - ssize_t ret; - - if(len <= 0) { - return len; + if (len <= 0) { + return NT_STATUS_OK; } - ret = read_socket_with_timeout(fd, buffer, len, len, timeout, - get_srv_read_error()); - - if (ret != len) { - cond_set_smb_read_error(get_srv_read_error(), - SMB_READ_ERROR); - return -1; - } - - return len; + return read_socket_with_timeout(fd, buffer, len, len, timeout, NULL); } /**************************************************************************** @@ -182,30 +153,29 @@ static ssize_t read_packet_remainder(int fd, (2*14) + /* word count (including bcc) */ \ 1 /* pad byte */) -static ssize_t receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx, - const char lenbuf[4], - int fd, - char **buffer, - unsigned int timeout, - size_t *p_unread) +static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx, + const char lenbuf[4], + int fd, char **buffer, + unsigned int timeout, + size_t *p_unread, + size_t *len_ret) { /* Size of a WRITEX call (+4 byte len). */ char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE]; ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */ ssize_t toread; - ssize_t ret; + NTSTATUS status; memcpy(writeX_header, lenbuf, sizeof(lenbuf)); - ret = read_socket_with_timeout(fd, writeX_header + 4, - STANDARD_WRITE_AND_X_HEADER_SIZE, - STANDARD_WRITE_AND_X_HEADER_SIZE, - timeout, get_srv_read_error()); + status = read_socket_with_timeout( + fd, writeX_header + 4, + STANDARD_WRITE_AND_X_HEADER_SIZE, + STANDARD_WRITE_AND_X_HEADER_SIZE, + timeout, NULL); - if (ret != STANDARD_WRITE_AND_X_HEADER_SIZE) { - cond_set_smb_read_error(get_srv_read_error(), - SMB_READ_ERROR); - return -1; + if (!NT_STATUS_IS_OK(status)) { + return status; } /* @@ -244,19 +214,17 @@ static ssize_t receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx, if (*buffer == NULL) { DEBUG(0, ("Could not allocate inbuf of length %d\n", (int)sizeof(writeX_header))); - cond_set_smb_read_error(get_srv_read_error(), - SMB_READ_ERROR); - return -1; + return NT_STATUS_NO_MEMORY; } /* Work out the remaining bytes. */ *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE; - - return newlen + 4; + *len_ret = newlen + 4; + return NT_STATUS_OK; } if (!valid_packet_size(len)) { - return -1; + return NT_STATUS_INVALID_PARAMETER; } /* @@ -269,9 +237,7 @@ static ssize_t receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx, if (*buffer == NULL) { DEBUG(0, ("Could not allocate inbuf of length %d\n", (int)len+4)); - cond_set_smb_read_error(get_srv_read_error(), - SMB_READ_ERROR); - return -1; + return NT_STATUS_NO_MEMORY; } /* Copy in what we already read. */ @@ -281,44 +247,34 @@ static ssize_t receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx, toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE; if(toread > 0) { - ret = read_packet_remainder(fd, - (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE, - timeout, - toread); - if (ret != toread) { - return -1; + status = read_packet_remainder( + fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE, + timeout, toread); + + if (!NT_STATUS_IS_OK(status)) { + return status; } } - return len + 4; + *len_ret = len + 4; + return NT_STATUS_OK; } -static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, - int fd, - char **buffer, - unsigned int timeout, - size_t *p_unread) +static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd, + char **buffer, unsigned int timeout, + size_t *p_unread, size_t *plen) { char lenbuf[4]; - ssize_t len,ret; + size_t len; int min_recv_size = lp_min_receive_file_size(); + NTSTATUS status; - set_smb_read_error(get_srv_read_error(),SMB_READ_OK); *p_unread = 0; - len = read_smb_length_return_keepalive(fd, lenbuf, - timeout, get_srv_read_error()); - if (len < 0) { - DEBUG(10,("receive_smb_raw: length < 0!\n")); - - /* - * Correct fix. smb_read_error may have already been - * set. Only set it here if not already set. Global - * variables still suck :-). JRA. - */ - - cond_set_smb_read_error(get_srv_read_error(),SMB_READ_ERROR); - return -1; + status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status))); + return status; } if (CVAL(lenbuf,0) == 0 && @@ -326,16 +282,18 @@ static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, smb_len_large(lenbuf) > min_recv_size && /* Could be a UNIX large writeX. */ !srv_is_signing_active()) { - return receive_smb_raw_talloc_partial_read(mem_ctx, - lenbuf, - fd, - buffer, - timeout, - p_unread); + status = receive_smb_raw_talloc_partial_read( + mem_ctx, lenbuf, fd, buffer, timeout, p_unread, &len); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("receive_smb_raw: %s\n", + nt_errstr(status))); + return status; + } } if (!valid_packet_size(len)) { - return -1; + return NT_STATUS_INVALID_PARAMETER; } /* @@ -347,46 +305,43 @@ static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, if (*buffer == NULL) { DEBUG(0, ("Could not allocate inbuf of length %d\n", (int)len+4)); - cond_set_smb_read_error(get_srv_read_error(),SMB_READ_ERROR); - return -1; + return NT_STATUS_NO_MEMORY; } memcpy(*buffer, lenbuf, sizeof(lenbuf)); - ret = read_packet_remainder(fd, (*buffer)+4, timeout, len); - if (ret != len) { - return -1; + status = read_packet_remainder(fd, (*buffer)+4, timeout, len); + if (!NT_STATUS_IS_OK(status)) { + return status; } - return len + 4; + *plen = len + 4; + return NT_STATUS_OK; } -static ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, - int fd, - char **buffer, - unsigned int timeout, - size_t *p_unread, - bool *p_encrypted) +static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, + char **buffer, unsigned int timeout, + size_t *p_unread, bool *p_encrypted, + size_t *p_len) { - ssize_t len; + size_t len = 0; + NTSTATUS status; *p_encrypted = false; - len = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout, p_unread); - - if (len < 0) { - return -1; + status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout, + p_unread, &len); + if (!NT_STATUS_IS_OK(status)) { + return status; } if (is_encrypted_packet((uint8_t *)*buffer)) { - NTSTATUS status = srv_decrypt_buffer(*buffer); + status = srv_decrypt_buffer(*buffer); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("receive_smb_talloc: SMB decryption failed on " "incoming packet! Error %s\n", nt_errstr(status) )); - cond_set_smb_read_error(get_srv_read_error(), - SMB_READ_BAD_DECRYPT); - return -1; + return status; } *p_encrypted = true; } @@ -395,11 +350,11 @@ static ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, if (!srv_check_sign_mac(*buffer, true)) { DEBUG(0, ("receive_smb: SMB Signature verification failed on " "incoming packet!\n")); - cond_set_smb_read_error(get_srv_read_error(),SMB_READ_BAD_SIG); - return -1; + return NT_STATUS_INVALID_NETWORK_RESPONSE; } - return len; + *p_len = len; + return NT_STATUS_OK; } /* @@ -756,21 +711,18 @@ static int select_on_fd(int fd, int maxfd, fd_set *fds) The timeout is in milliseconds ****************************************************************************/ -static bool receive_message_or_smb(TALLOC_CTX *mem_ctx, - char **buffer, - size_t *buffer_len, - int timeout, - size_t *p_unread, - bool *p_encrypted) +static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer, + size_t *buffer_len, int timeout, + size_t *p_unread, bool *p_encrypted) { fd_set r_fds, w_fds; int selrtn; struct timeval to; int maxfd = 0; - ssize_t len; + size_t len = 0; + NTSTATUS status; *p_unread = 0; - set_smb_read_error(get_srv_read_error(),SMB_READ_OK); again: @@ -824,8 +776,7 @@ static bool receive_message_or_smb(TALLOC_CTX *mem_ctx, msg->buf.length); if (*buffer == NULL) { DEBUG(0, ("talloc failed\n")); - set_smb_read_error(get_srv_read_error(),SMB_READ_ERROR); - return False; + return NT_STATUS_NO_MEMORY; } *buffer_len = msg->buf.length; *p_encrypted = msg->encrypted; @@ -833,7 +784,7 @@ static bool receive_message_or_smb(TALLOC_CTX *mem_ctx, /* We leave this message on the queue so the open code can know this is a retry. */ DEBUG(5,("receive_message_or_smb: returning deferred open smb message.\n")); - return True; + return NT_STATUS_OK; } } @@ -919,14 +870,12 @@ static bool receive_message_or_smb(TALLOC_CTX *mem_ctx, /* Check if error */ if (selrtn == -1) { /* something is wrong. Maybe the socket is dead? */ - set_smb_read_error(get_srv_read_error(),SMB_READ_ERROR); - return False; + return map_nt_error_from_unix(errno); } /* Did we timeout ? */ if (selrtn == 0) { - set_smb_read_error(get_srv_read_error(),SMB_READ_TIMEOUT); - return False; + return NT_STATUS_IO_TIMEOUT; } /* @@ -945,16 +894,16 @@ static bool receive_message_or_smb(TALLOC_CTX *mem_ctx, goto again; } - len = receive_smb_talloc(mem_ctx, smbd_server_fd(), - buffer, 0, p_unread, p_encrypted); + status = receive_smb_talloc(mem_ctx, smbd_server_fd(), buffer, 0, + p_unread, p_encrypted, &len); - if (len == -1) { - return False; + if (!NT_STATUS_IS_OK(status)) { + return status; } - *buffer_len = (size_t)len; + *buffer_len = len; - return True; + return NT_STATUS_OK; } /* @@ -1932,27 +1881,11 @@ void check_reload(time_t t) Process any timeout housekeeping. Return False if the caller should exit. ****************************************************************************/ -static bool timeout_processing(int *select_timeout, +static void timeout_processing(int *select_timeout, time_t *last_timeout_processing_time) { time_t t; - if (*get_srv_read_error() == SMB_READ_EOF) { - DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n")); - return false; - } - - if (*get_srv_read_error() == SMB_READ_ERROR) { - DEBUG(3,("timeout_processing: receive_smb error (%s) Exiting\n", - strerror(errno))); - return false; - } - - if (*get_srv_read_error() == SMB_READ_BAD_SIG) { - DEBUG(3,("timeout_processing: receive_smb error bad smb signature. Exiting\n")); - return false; - } - *last_timeout_processing_time = t = time(NULL); /* become root again if waiting */ @@ -1982,14 +1915,14 @@ static bool timeout_processing(int *select_timeout, if (secrets_lock_trust_account_password(lp_workgroup(), True) == False) { DEBUG(0,("process: unable to lock the machine account password for \ machine %s in domain %s.\n", global_myname(), lp_workgroup() )); - return True; + return; } if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) { DEBUG(0,("process: unable to read the machine account password for \ machine %s in domain %s.\n", global_myname(), lp_workgroup())); secrets_lock_trust_account_password(lp_workgroup(), False); - return True; + return; } /* @@ -1999,7 +1932,7 @@ machine %s in domain %s.\n", global_myname(), lp_workgroup())); if(t < lct + lp_machine_password_timeout()) { global_machine_password_needs_changing = False; secrets_lock_trust_account_password(lp_workgroup(), False); - return True; + return; } /* always just contact the PDC here */ @@ -2031,7 +1964,7 @@ machine %s in domain %s.\n", global_myname(), lp_workgroup())); *select_timeout = setup_select_timeout(); - return True; + return; } /**************************************************************************** @@ -2049,8 +1982,8 @@ void smbd_process(void) while (True) { int select_timeout = setup_select_timeout(); int num_echos; - char *inbuf; - size_t inbuf_len; + char *inbuf = NULL; + size_t inbuf_len = 0; bool encrypted = false; TALLOC_CTX *frame = talloc_stackframe_pool(8192); @@ -2058,21 +1991,35 @@ void smbd_process(void) /* Did someone ask for immediate checks on things like blocking locks ? */ if (select_timeout == 0) { - if(!timeout_processing(&select_timeout, - &last_timeout_processing_time)) - return; + timeout_processing(&select_timeout, + &last_timeout_processing_time); num_smbs = 0; /* Reset smb counter. */ } run_events(smbd_event_context(), 0, NULL, NULL); - while (!receive_message_or_smb(talloc_tos(), &inbuf, &inbuf_len, - select_timeout, - &unread_bytes, - &encrypted)) { - if(!timeout_processing(&select_timeout, - &last_timeout_processing_time)) - return; + while (True) { + NTSTATUS status; + + status = receive_message_or_smb( + talloc_tos(), &inbuf, &inbuf_len, + select_timeout, &unread_bytes, &encrypted); + + if (NT_STATUS_IS_OK(status)) { + break; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + timeout_processing( + &select_timeout, + &last_timeout_processing_time); + continue; + } + + DEBUG(3, ("receive_message_or_smb failed: %s, " + "exiting\n", nt_errstr(status))); + return; + num_smbs = 0; /* Reset smb counter. */ } @@ -2093,8 +2040,8 @@ void smbd_process(void) TALLOC_FREE(inbuf); if (smb_echo_count != num_echos) { - if(!timeout_processing( &select_timeout, &last_timeout_processing_time)) - return; + timeout_processing(&select_timeout, + &last_timeout_processing_time); num_smbs = 0; /* Reset smb counter. */ } @@ -2110,10 +2057,9 @@ void smbd_process(void) if ((num_smbs % 200) == 0) { time_t new_check_time = time(NULL); if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) { - if(!timeout_processing( - &select_timeout, - &last_timeout_processing_time)) - return; + timeout_processing( + &select_timeout, + &last_timeout_processing_time); num_smbs = 0; /* Reset smb counter. */ last_timeout_processing_time = new_check_time; /* Reset time. */ } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 18376031ec..bced8ed984 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3492,18 +3492,12 @@ void reply_writebraw(struct smb_request *req) } /* Now read the raw data into the buffer and write it */ - if (read_smb_length(smbd_server_fd(),buf, - SMB_SECONDARY_WAIT, get_srv_read_error()) == -1) { + status = read_smb_length(smbd_server_fd(), buf, SMB_SECONDARY_WAIT, + &numtowrite); + if (!NT_STATUS_IS_OK(status)) { exit_server_cleanly("secondary writebraw failed"); } - /* - * Even though this is not an smb message, - * smb_len returns the generic length of a packet. - */ - - numtowrite = smb_len(buf); - /* Set up outbuf to return the correct size */ reply_outbuf(req, 1, 0); @@ -3522,11 +3516,12 @@ void reply_writebraw(struct smb_request *req) (int)tcount,(int)nwritten,(int)numtowrite)); } - if (read_data(smbd_server_fd(), buf+4, numtowrite,get_srv_read_error()) - != numtowrite ) { + status = read_data(smbd_server_fd(), buf+4, numtowrite); + + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("reply_writebraw: Oversize secondary write " - "raw read failed (%s). Terminating\n", - strerror(errno) )); + "raw read failed (%s). Terminating\n", + nt_errstr(status))); exit_server_cleanly("secondary writebraw failed"); } |