mirror of
https://github.com/samba-team/samba.git
synced 2025-01-12 09:18:10 +03:00
started support for unicode on the wire in smbd. Using a very similar
method to what was used in the client I now have session setup and
tconx working.
Currently this is enabled with SMBD_USE_UNICODE environment
variable. Once the code is complete this will become a smb.conf
option.
(This used to be commit 7684c1e672
)
This commit is contained in:
parent
45c2ee3ff2
commit
b08b70faf8
@ -195,7 +195,7 @@ SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
|
||||
smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \
|
||||
smbd/posix_acls.o lib/msrpc-client.o lib/msrpc_use.o \
|
||||
smbd/process.o smbd/service.o smbd/error.o \
|
||||
printing/printfsp.o lib/util_seaccess.o
|
||||
printing/printfsp.o lib/util_seaccess.o smbd/srvstr.o
|
||||
|
||||
PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_cups.o printing/load.o
|
||||
|
||||
|
@ -353,6 +353,15 @@ void set_message_bcc(char *buf,int num_bytes)
|
||||
smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
setup only the byte count for a smb message, using the end of the
|
||||
message as a marker
|
||||
********************************************************************/
|
||||
void set_message_end(void *outbuf,void *end_ptr)
|
||||
{
|
||||
set_message_bcc(outbuf,PTR_DIFF(end_ptr,smb_buf(outbuf)));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
reduce a file name, removing .. elements.
|
||||
********************************************************************/
|
||||
|
@ -201,6 +201,12 @@ static int reply_nt1(char *outbuf)
|
||||
capabilities |= CAP_RAW_MODE;
|
||||
}
|
||||
|
||||
|
||||
/* until the unicode conversion is complete have it disabled by default */
|
||||
if (getenv("SMBD_USE_UNICODE")) {
|
||||
capabilities |= CAP_UNICODE;
|
||||
}
|
||||
|
||||
#ifdef WITH_MSDFS
|
||||
if(lp_host_msdfs())
|
||||
capabilities |= CAP_DFS;
|
||||
|
@ -273,12 +273,11 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
pstring user;
|
||||
pstring password;
|
||||
pstring devicename;
|
||||
BOOL doencrypt = SMBENCRYPT();
|
||||
int ecode = -1;
|
||||
uint16 vuid = SVAL(inbuf,smb_uid);
|
||||
int passlen = SVAL(inbuf,smb_vwv3);
|
||||
char *path;
|
||||
char *p;
|
||||
pstring path;
|
||||
char *p, *q;
|
||||
START_PROFILE(SMBtconX);
|
||||
|
||||
*service = *user = *password = *devicename = 0;
|
||||
@ -294,7 +293,8 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
|
||||
memcpy(password,smb_buf(inbuf),passlen);
|
||||
password[passlen]=0;
|
||||
path = smb_buf(inbuf) + passlen;
|
||||
p = smb_buf(inbuf) + passlen;
|
||||
p += srvstr_pull(inbuf, path, p, sizeof(path), -1, STR_TERMINATE|STR_CONVERT);
|
||||
|
||||
if (passlen != 24) {
|
||||
if (strequal(password," "))
|
||||
@ -302,28 +302,21 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
passlen = strlen(password);
|
||||
}
|
||||
|
||||
p = strchr(path+2,'\\');
|
||||
if (!p) {
|
||||
q = strchr(path+2,'\\');
|
||||
if (!q) {
|
||||
END_PROFILE(SMBtconX);
|
||||
return(ERROR(ERRDOS,ERRnosuchshare));
|
||||
}
|
||||
fstrcpy(service,p+1);
|
||||
p = strchr(service,'%');
|
||||
if (p) {
|
||||
*p++ = 0;
|
||||
fstrcpy(user,p);
|
||||
fstrcpy(service,q+1);
|
||||
q = strchr(service,'%');
|
||||
if (q) {
|
||||
*q++ = 0;
|
||||
fstrcpy(user,q);
|
||||
}
|
||||
StrnCpy(devicename,path + strlen(path) + 1,6);
|
||||
p += srvstr_pull(inbuf, devicename, p, sizeof(devicename), 6, STR_CONVERT);
|
||||
|
||||
DEBUG(4,("Got device type %s\n",devicename));
|
||||
|
||||
/*
|
||||
* Ensure the user and password names are in UNIX codepage format.
|
||||
*/
|
||||
|
||||
dos_to_unix(user,True);
|
||||
if (!doencrypt)
|
||||
dos_to_unix(password,True);
|
||||
|
||||
/*
|
||||
* Pass the user through the NT -> unix user mapping
|
||||
* function.
|
||||
@ -349,13 +342,13 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
} else {
|
||||
char *fsname = lp_fstype(SNUM(conn));
|
||||
|
||||
set_message(outbuf,3,3,True);
|
||||
set_message(outbuf,3,0,True);
|
||||
|
||||
p = smb_buf(outbuf);
|
||||
pstrcpy(p,devicename); p = skip_string(p,1); /* device name */
|
||||
pstrcpy(p,fsname); p = skip_string(p,1); /* filesystem type e.g NTFS */
|
||||
p += srvstr_push(inbuf, outbuf, p, devicename, -1, STR_CONVERT|STR_TERMINATE);
|
||||
p += srvstr_push(inbuf, outbuf, p, fsname, -1, STR_CONVERT|STR_TERMINATE);
|
||||
|
||||
set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
|
||||
set_message_end(outbuf,p);
|
||||
|
||||
/* what does setting this bit do? It is set by NT4 and
|
||||
may affect the ability to autorun mounted cdroms */
|
||||
@ -703,10 +696,12 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
|
||||
BOOL valid_lm_password = False;
|
||||
pstring user;
|
||||
pstring orig_user;
|
||||
fstring domain;
|
||||
fstring native_os;
|
||||
fstring native_lanman;
|
||||
BOOL guest=False;
|
||||
static BOOL done_sesssetup = False;
|
||||
BOOL doencrypt = SMBENCRYPT();
|
||||
char *domain = "";
|
||||
START_PROFILE(SMBsesssetupX);
|
||||
|
||||
*smb_apasswd = 0;
|
||||
@ -835,17 +830,19 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
|
||||
}
|
||||
|
||||
p += passlen1 + passlen2;
|
||||
fstrcpy(user,p);
|
||||
p = skip_string(p,1);
|
||||
p += srvstr_pull(inbuf, user, p, sizeof(user), -1, STR_CONVERT|STR_TERMINATE);
|
||||
/*
|
||||
* Incoming user and domain are in DOS codepage format. Convert
|
||||
* to UNIX.
|
||||
*/
|
||||
dos_to_unix(user,True);
|
||||
domain = p;
|
||||
dos_to_unix(domain, True);
|
||||
p += srvstr_pull(inbuf, domain, p, sizeof(domain),
|
||||
-1, STR_CONVERT|STR_TERMINATE);
|
||||
p += srvstr_pull(inbuf, native_os, p, sizeof(native_os),
|
||||
-1, STR_CONVERT|STR_TERMINATE);
|
||||
p += srvstr_pull(inbuf, native_lanman, p, sizeof(native_lanman),
|
||||
-1, STR_CONVERT|STR_TERMINATE);
|
||||
DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
|
||||
domain,skip_string(p,1),skip_string(p,2)));
|
||||
domain,native_os,native_lanman));
|
||||
}
|
||||
|
||||
DEBUG(3,("sesssetupX:name=[%s]\n",user));
|
||||
@ -1027,12 +1024,12 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
|
||||
set_message(outbuf,3,0,True);
|
||||
} else {
|
||||
char *p;
|
||||
set_message(outbuf,3,3,True);
|
||||
set_message(outbuf,3,0,True);
|
||||
p = smb_buf(outbuf);
|
||||
pstrcpy(p,"Unix"); p = skip_string(p,1);
|
||||
pstrcpy(p,"Samba "); pstrcat(p,VERSION); p = skip_string(p,1);
|
||||
pstrcpy(p,global_myworkgroup); unix_to_dos(p, True); p = skip_string(p,1);
|
||||
set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
|
||||
p += srvstr_push(inbuf, outbuf, p, "Unix", -1, STR_TERMINATE|STR_CONVERT);
|
||||
p += srvstr_push(inbuf, outbuf, p, "Samba", -1, STR_TERMINATE|STR_CONVERT);
|
||||
p += srvstr_push(inbuf, outbuf, p, global_myworkgroup, -1, STR_TERMINATE|STR_CONVERT);
|
||||
set_message_end(outbuf,p);
|
||||
/* perhaps grab OS version here?? */
|
||||
}
|
||||
|
||||
|
186
source3/smbd/srvstr.c
Normal file
186
source3/smbd/srvstr.c
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 3.0
|
||||
server specific string routines
|
||||
Copyright (C) Andrew Tridgell 2001
|
||||
|
||||
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 2 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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define NO_SYSLOG
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#define UNICODE_FLAG() (SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
|
||||
|
||||
/****************************************************************************
|
||||
copy a string from a char* src to a unicode or ascii
|
||||
dos code page destination choosing unicode or ascii based on the
|
||||
FLAGS2_UNICODE_STRINGS bit in inbuf
|
||||
return the number of bytes occupied by the string in the destination
|
||||
flags can have:
|
||||
STR_TERMINATE means include the null termination
|
||||
STR_CONVERT means convert from unix to dos codepage
|
||||
STR_UPPER means uppercase in the destination
|
||||
STR_ASCII use ascii even with unicode servers
|
||||
dest_len is the maximum length allowed in the destination. If dest_len
|
||||
is -1 then no maxiumum is used
|
||||
****************************************************************************/
|
||||
int srvstr_push(void *inbuf, void *outbuf, void *dest, const char *src, int dest_len, int flags)
|
||||
{
|
||||
int len=0;
|
||||
|
||||
/* treat a pstring as "unlimited" length */
|
||||
if (dest_len == -1) {
|
||||
dest_len = sizeof(pstring);
|
||||
}
|
||||
|
||||
if (!(flags & STR_ASCII) && srvstr_align(inbuf, PTR_DIFF(dest, outbuf))) {
|
||||
*(char *)dest = 0;
|
||||
dest++;
|
||||
dest_len--;
|
||||
len++;
|
||||
}
|
||||
|
||||
if ((flags & STR_ASCII) || !UNICODE_FLAG()) {
|
||||
/* the client doesn't want unicode */
|
||||
safe_strcpy(dest, src, dest_len);
|
||||
len = strlen(dest);
|
||||
if (flags & STR_TERMINATE) len++;
|
||||
if (flags & STR_CONVERT) unix_to_dos(dest,True);
|
||||
if (flags & STR_UPPER) strupper(dest);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* the server likes unicode. give it the works */
|
||||
if (flags & STR_CONVERT) {
|
||||
dos_PutUniCode(dest, src, dest_len, flags & STR_TERMINATE);
|
||||
} else {
|
||||
ascii_to_unistr(dest, src, dest_len);
|
||||
}
|
||||
if (flags & STR_UPPER) {
|
||||
strupper_w(dest);
|
||||
}
|
||||
len += strlen(src)*2;
|
||||
if (flags & STR_TERMINATE) len += 2;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
return the length that a string would occupy when copied with srvstr_push()
|
||||
STR_TERMINATE means include the null termination
|
||||
STR_CONVERT means convert from unix to dos codepage
|
||||
STR_UPPER means uppercase in the destination
|
||||
note that dest is only used for alignment purposes. No data is written.
|
||||
****************************************************************************/
|
||||
int srvstr_push_size(void *inbuf, void *outbuf,
|
||||
const void *dest, const char *src, int dest_len, int flags)
|
||||
{
|
||||
int len = strlen(src);
|
||||
if (flags & STR_TERMINATE) len++;
|
||||
if (!(flags & STR_ASCII) && UNICODE_FLAG()) len *= 2;
|
||||
|
||||
if (!(flags & STR_ASCII) && dest && srvstr_align(inbuf, PTR_DIFF(outbuf, dest))) {
|
||||
len++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
copy a string from a unicode or ascii source (depending on flg2)
|
||||
to a char* destination
|
||||
flags can have:
|
||||
STR_CONVERT means convert from dos to unix codepage
|
||||
STR_TERMINATE means the string in src is null terminated
|
||||
STR_UNICODE means to force as unicode
|
||||
if STR_TERMINATE is set then src_len is ignored
|
||||
src_len is the length of the source area in bytes
|
||||
return the number of bytes occupied by the string in src
|
||||
****************************************************************************/
|
||||
int srvstr_pull(void *inbuf, char *dest, const void *src, int dest_len, int src_len, int flags)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (dest_len == -1) {
|
||||
dest_len = sizeof(pstring);
|
||||
}
|
||||
|
||||
if (srvstr_align(inbuf, PTR_DIFF(src, inbuf))) {
|
||||
src++;
|
||||
if (src_len > 0) src_len--;
|
||||
}
|
||||
|
||||
if (!(flags & STR_UNICODE) && !UNICODE_FLAG()) {
|
||||
/* the server doesn't want unicode */
|
||||
if (flags & STR_TERMINATE) {
|
||||
safe_strcpy(dest, src, dest_len);
|
||||
len = strlen(src)+1;
|
||||
} else {
|
||||
if (src_len > dest_len) src_len = dest_len;
|
||||
len = src_len;
|
||||
memcpy(dest, src, len);
|
||||
dest[len] = 0;
|
||||
}
|
||||
if (flags & STR_CONVERT) dos_to_unix(dest,True);
|
||||
return len;
|
||||
}
|
||||
|
||||
if (flags & STR_TERMINATE) {
|
||||
unistr_to_ascii(dest, src, dest_len);
|
||||
len = strlen(dest)*2 + 2;
|
||||
} else {
|
||||
int i, c;
|
||||
if (dest_len*2 < src_len) src_len = 2*dest_len;
|
||||
for (i=0; i < src_len; i += 2) {
|
||||
c = SVAL(src, i);
|
||||
*dest++ = c;
|
||||
}
|
||||
*dest++ = 0;
|
||||
len = src_len;
|
||||
}
|
||||
if (flags & STR_CONVERT) dos_to_unix(dest,True);
|
||||
return len;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
return the length that a string would occupy (not including the null)
|
||||
when copied with srvstr_pull()
|
||||
if src_len is -1 then assume the source is null terminated
|
||||
****************************************************************************/
|
||||
int srvstr_pull_size(void *inbuf, const void *src, int src_len)
|
||||
{
|
||||
if (srvstr_align(inbuf, PTR_DIFF(src, inbuf))) {
|
||||
src++;
|
||||
if (src_len > 0) src_len--;
|
||||
}
|
||||
|
||||
if (!UNICODE_FLAG()) {
|
||||
return strlen(src);
|
||||
}
|
||||
return strlen_w(src);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
return an alignment of either 0 or 1
|
||||
if unicode is not negotiated then return 0
|
||||
otherwise return 1 if offset is off
|
||||
****************************************************************************/
|
||||
int srvstr_align(void *inbuf, int offset)
|
||||
{
|
||||
if (!UNICODE_FLAG()) return 0;
|
||||
return offset & 1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user