From 8f1404739fe75464fe1500c3f6e6d39d4878ec1e Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 12 Jul 1999 18:46:15 +0000 Subject: Jean-Francois Micouleau's rewritten DFS patch, originally written by Nigel Williams. despite the data format being *exactly* the same as NT's, this still doesn't work yet. more work needed. (This used to be commit 270981960bb5aab52d2f8e494827101ece6729c4) --- source3/Makefile.in | 2 +- source3/include/proto.h | 14 ++ source3/include/smb.h | 15 +- source3/param/loadparm.c | 4 +- source3/smbd/negprot.c | 7 + source3/smbd/nttrans.c | 1 + source3/smbd/process.c | 2 +- source3/smbd/reply.c | 10 ++ source3/smbd/server.c | 3 + source3/smbd/trans2.c | 398 +++++++++++++++++++++++++++++++++++++++-------- 10 files changed, 381 insertions(+), 75 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 51558de749..544dbf3974 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -184,7 +184,7 @@ SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/$(QUOTAOBJS) smbd/reply.o smbd/ssl.o smbd/trans2.o smbd/uid.o \ smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o smbd/blocking.o \ smbd/process.o smbd/oplock.o smbd/service.o smbd/error.o smbd/vfs.o \ - smbd/vfs-wrap.o printing/nt_printing.o + smbd/vfs-wrap.o printing/nt_printing.o smbd/dfs.o PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/printing.o diff --git a/source3/include/proto.h b/source3/include/proto.h index 59fdb28672..182c74ed6f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6,6 +6,11 @@ /*The following definitions come from client/client.c */ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, BOOL dirs); +void complete_process_file(file_info *f); +char *complete_remote_file(char *text, int state); +char *complete_cmd(char *text, int state); +char **completion_fn(char *text, int start, int end); +char *complete_cmd_null(char *text, int state); struct cli_state *do_connect(char *server, char *share, int smb_port); /*The following definitions come from client/clitar.c */ @@ -1250,6 +1255,7 @@ char *lp_driverfile(void); char *lp_panic_action(void); char *lp_nt_forms(void); char *lp_nt_drivers_file(void); +char *lp_dfs_map(void); char *lp_ldap_server(void); char *lp_ldap_suffix(void); char *lp_ldap_bind_as(void); @@ -3245,6 +3251,9 @@ void display_eventlog_eventrecord(FILE *out_hnd, enum action_type action, EVENTL /*The following definitions come from rpcclient/rpcclient.c */ void rpcclient_init(void); +char *complete_cmd(char *text, int state); +char **completion_fn(char *text, int start, int end); +char *complete_cmd_null(char *text, int state); /*The following definitions come from smbd/blocking.c */ @@ -3297,6 +3306,11 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO SMB_BIG_UINT sys_disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize); +/*The following definitions come from smbd/dfs.c */ + +BOOL init_dfs_table(void); +int under_dfs(connection_struct *conn, const char *path); + /*The following definitions come from smbd/dir.c */ void init_dptrs(void); diff --git a/source3/include/smb.h b/source3/include/smb.h index 82fab11929..4541329c78 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1218,12 +1218,13 @@ struct bitmap { #define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11 /* These are the NT transact sub commands. */ -#define NT_TRANSACT_CREATE 1 -#define NT_TRANSACT_IOCTL 2 -#define NT_TRANSACT_SET_SECURITY_DESC 3 -#define NT_TRANSACT_NOTIFY_CHANGE 4 -#define NT_TRANSACT_RENAME 5 -#define NT_TRANSACT_QUERY_SECURITY_DESC 6 +#define NT_TRANSACT_CREATE 1 +#define NT_TRANSACT_IOCTL 2 +#define NT_TRANSACT_SET_SECURITY_DESC 3 +#define NT_TRANSACT_NOTIFY_CHANGE 4 +#define NT_TRANSACT_RENAME 5 +#define NT_TRANSACT_QUERY_SECURITY_DESC 6 +#define NT_TRANSACT_GET_DFS_REFERRAL 0x10 /* these are the trans2 sub fields for primary requests */ #define smb_tpscnt smb_vwv0 @@ -1805,6 +1806,8 @@ struct nmb_name { #include "client.h" #include "rpcclient.h" +#include "dfs.h" + /* * Size of new password account encoding string. DO NOT CHANGE. */ diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 7811d58afb..3f89c53be4 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -146,6 +146,7 @@ typedef struct char *szDomainOtherSIDs; char *szDriverFile; char *szNameResolveOrder; + char *szDfsMap; #ifdef WITH_LDAP char *szLdapServer; char *szLdapSuffix; @@ -556,6 +557,7 @@ static struct parm_struct parm_table[] = {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0}, {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0}, {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0}, + {"dfs map", P_STRING, P_GLOBAL, &Globals.szDfsMap, NULL, NULL, 0}, {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL|FLAG_DEPRECATED}, {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL}, {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL}, @@ -589,7 +591,6 @@ static struct parm_struct parm_table[] = {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0}, {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT}, {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0}, - #ifdef WITH_SSL {"Secure Socket Layer Options", P_SEP, P_SEPARATOR}, @@ -1212,6 +1213,7 @@ FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile) FN_GLOBAL_STRING(lp_panic_action,&Globals.szPanicAction) FN_GLOBAL_STRING(lp_nt_forms,&Globals.szNtForms) FN_GLOBAL_STRING(lp_nt_drivers_file,&Globals.szNtDriverFile) +FN_GLOBAL_STRING(lp_dfs_map,&Globals.szDfsMap) #ifdef WITH_LDAP FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer); diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index e66bf9f163..51ec963b8c 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -27,6 +27,7 @@ extern int max_recv; extern fstring global_myworkgroup; extern fstring remote_machine; extern pstring myhostname; +extern dfs_internal dfs_struct; /**************************************************************************** reply for the core protocol @@ -178,6 +179,12 @@ static int reply_nt1(char *outbuf) { capabilities |= CAP_LARGE_FILES; } + + if (dfs_struct.ready==True) + { + capabilities |= CAP_DFS; + } + /* other valid capabilities which we may support at some time... CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 5c26c7f578..657dd8b130 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1666,6 +1666,7 @@ due to being in oplock break state.\n" )); length, bufsize, &setup, ¶ms, &data); break; + default: /* Error in request */ DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code)); diff --git a/source3/smbd/process.c b/source3/smbd/process.c index a4c1acba8f..bc60cb474d 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -339,7 +339,7 @@ struct smb_message_struct /* LANMAN2.0 PROTOCOL FOLLOWS */ {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER}, {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER}, - {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER }, + {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | CAN_IPC}, {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER}, /* NT PROTOCOL FOLLOWS */ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 29dccaf9e8..652d6e4795 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -835,6 +835,11 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size unix_convert(name,conn,0,&bad_path,&st); mode = SVAL(inbuf,smb_vwv0); + + if(under_dfs(conn, name)) { + SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); + return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED)); + } if (check_name(name,conn)) { if(VALID_STAT(st)) @@ -892,6 +897,11 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size BOOL bad_path = False; pstrcpy(fname,smb_buf(inbuf) + 1); + + if (under_dfs(conn, fname)) { + SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); + return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED)); + } /* dos smetimes asks for a stat of "" - it returns a "hidden directory" under WfWg - weird! */ diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 339fab8398..4ea39e14c6 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -27,6 +27,7 @@ extern pstring debugf; extern fstring global_myworkgroup; extern fstring global_sam_name; extern pstring global_myname; +extern dfs_internal dfs_struct; int am_parent = 1; @@ -50,6 +51,7 @@ extern fstring remote_machine; extern pstring OriginalDir; extern pstring myhostname; + /**************************************************************************** when exiting, take the whole family ****************************************************************************/ @@ -452,6 +454,7 @@ static void init_structs(void) init_lsa_policy_hnd(); /* for LSA handles */ init_printer_hnd(); /* for SPOOLSS handles */ init_dptrs(); + init_dfs_table(); } /**************************************************************************** diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 8a182399e7..381f4ed392 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -31,6 +31,7 @@ extern int Client; extern int smb_read_error; extern fstring local_machine; extern int global_oplock_break; +extern dfs_internal dfs_struct; /**************************************************************************** Send the required number of replies back. @@ -112,7 +113,8 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params, SSVAL(outbuf,smb_prcnt, params_sent_thistime); if(params_sent_thistime == 0) { - SSVAL(outbuf,smb_proff,0); + /*SSVAL(outbuf,smb_proff,0);*/ + SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf))); SSVAL(outbuf,smb_prdisp,0); } else @@ -2019,6 +2021,238 @@ int reply_findnclose(connection_struct *conn, return(outsize); } +/**************************************************************************** + reply to a TRANS2_GET_DFS_REFERRAL + ****************************************************************************/ +static int call_trans2getdfsreferral(connection_struct *conn, + char *inbuf, char *outbuf, int length, + int bufsize, + char **pparams, char **ppdata, + int total_data) +{ + char *params = *pparams; + char *pdata; + char *pheader; + char *localstring_offset; + char *mangledstring_offset; + char *sharename_offset; + char *referal_offset; + + int i; + int j; + unsigned int total_params = SVAL(inbuf, smb_tpscnt); + int query_file_len=0; + int bytesreq=0; + int filename_len; + + BOOL first_one=True; + + referal_trans_param rtp; + dfs_internal_table *list=dfs_struct.table; + dfs_response reply; + + DEBUG(0,("call_trans2getdfsreferral:1\n")); + + ZERO_STRUCT(rtp); + /* decode the param member of query */ + rtp.level=SVAL(params, 0); + DEBUGADD(0,("rtp.level:[%d]\n",rtp.level)); + + DEBUGADD(0,("total_params:[%d]\n",total_params)); + for (i=0; i<(total_params-2)/2; i++) + { + rtp.directory[i]=SVAL(params, 2+2*i); + } +/* + strupper(rtp.directory); +*/ + query_file_len=strlen(rtp.directory); + DEBUGADD(0,("rtp.directory:[%s]\n",rtp.directory)); + DEBUGADD(0,("query_file_len:[%d]\n",query_file_len)); + + /* + lookup in the internal DFS table all the entries + and calculate the required data buffer size + */ + bytesreq=8; /* the header */ + reply.number_of_referal=0; + DEBUGADD(0,("call_trans2getdfsreferral:2\n")); + + for(i=0; i