Line data Source code
1 : /* 2 : Unix SMB/CIFS implementation. 3 : server specific string routines 4 : Copyright (C) Andrew Tridgell 2001 5 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003 6 : 7 : This program is free software; you can redistribute it and/or modify 8 : it under the terms of the GNU General Public License as published by 9 : the Free Software Foundation; either version 3 of the License, or 10 : (at your option) any later version. 11 : 12 : This program is distributed in the hope that it will be useful, 13 : but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : GNU General Public License for more details. 16 : 17 : You should have received a copy of the GNU General Public License 18 : along with this program. If not, see <http://www.gnu.org/licenses/>. 19 : */ 20 : 21 : #include "includes.h" 22 : #include "smbd/smbd.h" 23 : #include "smbd/globals.h" 24 : #include "lib/util/string_wrappers.h" 25 : 26 : /* Make sure we can't write a string past the end of the buffer */ 27 : 28 1037518 : NTSTATUS srvstr_push_fn(const char *base_ptr, uint16_t smb_flags2, void *dest, 29 : const char *src, int dest_len, int flags, size_t *ret_len) 30 : { 31 1182 : size_t len; 32 1182 : int saved_errno; 33 1182 : NTSTATUS status; 34 : 35 1037518 : if (dest_len < 0) { 36 0 : return NT_STATUS_INVALID_PARAMETER; 37 : } 38 : 39 1037518 : saved_errno = errno; 40 1037518 : errno = 0; 41 : 42 : /* 'normal' push into size-specified buffer */ 43 1037518 : len = push_string_base(base_ptr, smb_flags2, dest, src, 44 : dest_len, flags); 45 : 46 1037518 : if (errno != 0) { 47 : /* 48 : * Special case E2BIG, EILSEQ, EINVAL 49 : * as they mean conversion errors here, 50 : * but we don't generically map them as 51 : * they can mean different things in 52 : * generic filesystem calls (such as 53 : * read xattrs). 54 : */ 55 80 : if (errno == E2BIG || errno == EILSEQ || errno == EINVAL) { 56 80 : status = NT_STATUS_ILLEGAL_CHARACTER; 57 : } else { 58 0 : status = map_nt_error_from_unix_common(errno); 59 : /* 60 : * Paranoia - Filter out STATUS_MORE_ENTRIES. 61 : * I don't think we can get this but it has a 62 : * specific meaning to the client. 63 : */ 64 0 : if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { 65 0 : status = NT_STATUS_UNSUCCESSFUL; 66 : } 67 : } 68 80 : DEBUG(10,("character conversion failure " 69 : "on string (%s) (%s)\n", 70 : src, strerror(errno))); 71 : } else { 72 : /* Success - restore untouched errno. */ 73 1037438 : errno = saved_errno; 74 1037438 : *ret_len = len; 75 1037438 : status = NT_STATUS_OK; 76 : } 77 1037518 : return status; 78 : }