smbd/nttrans.c

ソースコードを見る。

関数

static char * nttrans_realloc (char **ptr, size_t size)
int send_nt_replies (char *outbuf, int bufsize, NTSTATUS nt_error, char *params, int paramsize, char *pdata, int datasize)
BOOL is_ntfs_stream_name (const char *fname)
static uint32 set_posix_case_semantics (connection_struct *conn, uint32 file_attributes)
static void restore_case_semantics (connection_struct *conn, uint32 file_attributes)
static int nt_open_pipe (char *fname, connection_struct *conn, char *inbuf, char *outbuf, int *ppnum)
static int do_ntcreate_pipe_open (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize)
int reply_ntcreate_and_X_quota (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, enum FAKE_FILE_TYPE fake_file_type, const char *fname)
int reply_ntcreate_and_X (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize)
static int do_nt_transact_create_pipe (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count)
static NTSTATUS set_sd (files_struct *fsp, char *data, uint32 sd_len, uint32 security_info_sent)
static struct ea_listread_nttrans_ea_list (TALLOC_CTX *ctx, const char *pdata, size_t data_size)
static int call_nt_transact_create (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count)
int reply_ntcancel (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize)
static NTSTATUS copy_internals (connection_struct *conn, char *oldname, char *newname, uint32 attrs)
int reply_ntrename (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize)
static int call_nt_transact_notify_change (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count, uint32 max_param_count)
static int call_nt_transact_rename (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count)
static size_t get_null_nt_acl (TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
static int call_nt_transact_query_security_desc (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count)
static int call_nt_transact_set_security_desc (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count)
static int call_nt_transact_ioctl (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count)
static int call_nt_transact_get_user_quota (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count)
static int call_nt_transact_set_user_quota (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count)
static int handle_nttrans (connection_struct *conn, struct trans_state *state, char *inbuf, char *outbuf, int size, int bufsize)
int reply_nttrans (connection_struct *conn, char *inbuf, char *outbuf, int size, int bufsize)
int reply_nttranss (connection_struct *conn, char *inbuf, char *outbuf, int size, int bufsize)

変数

int max_send
enum protocol_types Protocol
int smb_read_error
current_user current_user
static const char * known_nt_pipes []
static BOOL saved_case_sensitive
static BOOL saved_case_preserve
static BOOL saved_short_case_preserve


関数

static char* nttrans_realloc ( char **  ptr,
size_t  size 
) [static]

nttrans.c50 行で定義されています。

参照先 smb_panic().

参照元 call_nt_transact_create()call_nt_transact_get_user_quota()call_nt_transact_ioctl()call_nt_transact_query_security_desc()do_nt_transact_create_pipe().

00051 {
00052         if (ptr==NULL) {
00053                 smb_panic("nttrans_realloc() called with NULL ptr\n");
00054         }
00055                 
00056         *ptr = (char *)SMB_REALLOC(*ptr, size);
00057         if(*ptr == NULL) {
00058                 return NULL;
00059         }
00060         memset(*ptr,'\0',size);
00061         return *ptr;
00062 }

int send_nt_replies ( char *  outbuf,
int  bufsize,
NTSTATUS  nt_error,
char *  params,
int  paramsize,
char *  pdata,
int  datasize 
)

nttrans.c71 行で定義されています。

参照先 exit_server_cleanly()max_sendsend_smb()set_message()show_msg()smbd_server_fd().

参照元 call_nt_transact_create()call_nt_transact_get_user_quota()call_nt_transact_ioctl()call_nt_transact_query_security_desc()call_nt_transact_rename()call_nt_transact_set_security_desc()call_nt_transact_set_user_quota()change_notify_reply()do_nt_transact_create_pipe().

00073 {
00074         int data_to_send = datasize;
00075         int params_to_send = paramsize;
00076         int useable_space;
00077         char *pp = params;
00078         char *pd = pdata;
00079         int params_sent_thistime, data_sent_thistime, total_sent_thistime;
00080         int alignment_offset = 3;
00081         int data_alignment_offset = 0;
00082 
00083         /*
00084          * Initially set the wcnt area to be 18 - this is true for all
00085          * transNT replies.
00086          */
00087 
00088         set_message(outbuf,18,0,True);
00089 
00090         if (NT_STATUS_V(nt_error)) {
00091                 ERROR_NT(nt_error);
00092         }
00093 
00094         /* 
00095          * If there genuinely are no parameters or data to send just send
00096          * the empty packet.
00097          */
00098 
00099         if(params_to_send == 0 && data_to_send == 0) {
00100                 show_msg(outbuf);
00101                 if (!send_smb(smbd_server_fd(),outbuf)) {
00102                         exit_server_cleanly("send_nt_replies: send_smb failed.");
00103                 }
00104                 return 0;
00105         }
00106 
00107         /*
00108          * When sending params and data ensure that both are nicely aligned.
00109          * Only do this alignment when there is also data to send - else
00110          * can cause NT redirector problems.
00111          */
00112 
00113         if (((params_to_send % 4) != 0) && (data_to_send != 0)) {
00114                 data_alignment_offset = 4 - (params_to_send % 4);
00115         }
00116 
00117         /* 
00118          * Space is bufsize minus Netbios over TCP header minus SMB header.
00119          * The alignment_offset is to align the param bytes on a four byte
00120          * boundary (2 bytes for data len, one byte pad). 
00121          * NT needs this to work correctly.
00122          */
00123 
00124         useable_space = bufsize - ((smb_buf(outbuf)+
00125                                 alignment_offset+data_alignment_offset) -
00126                                 outbuf);
00127 
00128         /*
00129          * useable_space can never be more than max_send minus the
00130          * alignment offset.
00131          */
00132 
00133         useable_space = MIN(useable_space,
00134                                 max_send - (alignment_offset+data_alignment_offset));
00135 
00136 
00137         while (params_to_send || data_to_send) {
00138 
00139                 /*
00140                  * Calculate whether we will totally or partially fill this packet.
00141                  */
00142 
00143                 total_sent_thistime = params_to_send + data_to_send +
00144                                         alignment_offset + data_alignment_offset;
00145 
00146                 /* 
00147                  * We can never send more than useable_space.
00148                  */
00149 
00150                 total_sent_thistime = MIN(total_sent_thistime, useable_space);
00151 
00152                 set_message(outbuf, 18, total_sent_thistime, True);
00153 
00154                 /*
00155                  * Set total params and data to be sent.
00156                  */
00157 
00158                 SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);
00159                 SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);
00160 
00161                 /* 
00162                  * Calculate how many parameters and data we can fit into
00163                  * this packet. Parameters get precedence.
00164                  */
00165 
00166                 params_sent_thistime = MIN(params_to_send,useable_space);
00167                 data_sent_thistime = useable_space - params_sent_thistime;
00168                 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
00169 
00170                 SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);
00171 
00172                 if(params_sent_thistime == 0) {
00173                         SIVAL(outbuf,smb_ntr_ParameterOffset,0);
00174                         SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);
00175                 } else {
00176                         /*
00177                          * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
00178                          * parameter bytes, however the first 4 bytes of outbuf are
00179                          * the Netbios over TCP header. Thus use smb_base() to subtract
00180                          * them from the calculation.
00181                          */
00182 
00183                         SIVAL(outbuf,smb_ntr_ParameterOffset,
00184                                 ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
00185                         /* 
00186                          * Absolute displacement of param bytes sent in this packet.
00187                          */
00188 
00189                         SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);
00190                 }
00191 
00192                 /*
00193                  * Deal with the data portion.
00194                  */
00195 
00196                 SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);
00197 
00198                 if(data_sent_thistime == 0) {
00199                         SIVAL(outbuf,smb_ntr_DataOffset,0);
00200                         SIVAL(outbuf,smb_ntr_DataDisplacement, 0);
00201                 } else {
00202                         /*
00203                          * The offset of the data bytes is the offset of the
00204                          * parameter bytes plus the number of parameters being sent this time.
00205                          */
00206 
00207                         SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -
00208                                 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
00209                                 SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);
00210                 }
00211 
00212                 /* 
00213                  * Copy the param bytes into the packet.
00214                  */
00215 
00216                 if(params_sent_thistime) {
00217                         memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
00218                 }
00219 
00220                 /*
00221                  * Copy in the data bytes
00222                  */
00223 
00224                 if(data_sent_thistime) {
00225                         memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
00226                                 data_alignment_offset,pd,data_sent_thistime);
00227                 }
00228     
00229                 DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
00230                         params_sent_thistime, data_sent_thistime, useable_space));
00231                 DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
00232                         params_to_send, data_to_send, paramsize, datasize));
00233     
00234                 /* Send the packet */
00235                 show_msg(outbuf);
00236                 if (!send_smb(smbd_server_fd(),outbuf)) {
00237                         exit_server_cleanly("send_nt_replies: send_smb failed.");
00238                 }
00239     
00240                 pp += params_sent_thistime;
00241                 pd += data_sent_thistime;
00242     
00243                 params_to_send -= params_sent_thistime;
00244                 data_to_send -= data_sent_thistime;
00245 
00246                 /*
00247                  * Sanity check
00248                  */
00249 
00250                 if(params_to_send < 0 || data_to_send < 0) {
00251                         DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
00252                                 params_to_send, data_to_send));
00253                         return -1;
00254                 }
00255         } 
00256 
00257         return 0;
00258 }

BOOL is_ntfs_stream_name ( const char *  fname  ) 

nttrans.c264 行で定義されています。

参照先 strchr_m().

参照元 call_nt_transact_create()open_directory()reply_ntcreate_and_X()reply_ntrename().

00265 {
00266         if (lp_posix_pathnames()) {
00267                 return False;
00268         }
00269         return (strchr_m(fname, ':') != NULL) ? True : False;
00270 }

static uint32 set_posix_case_semantics ( connection_struct conn,
uint32  file_attributes 
) [static]

nttrans.c284 行で定義されています。

参照先 connection_struct::case_preserveconnection_struct::case_sensitivecurrent_user::connsaved_case_preservesaved_case_sensitivesaved_short_case_preserveconnection_struct::short_case_preserve.

参照元 call_nt_transact_create()reply_ntcreate_and_X().

00285 {
00286         if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
00287                 return file_attributes;
00288         }
00289 
00290         saved_case_sensitive = conn->case_sensitive;
00291         saved_case_preserve = conn->case_preserve;
00292         saved_short_case_preserve = conn->short_case_preserve;
00293 
00294         /* Set to POSIX. */
00295         conn->case_sensitive = True;
00296         conn->case_preserve = True;
00297         conn->short_case_preserve = True;
00298 
00299         return (file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
00300 }

static void restore_case_semantics ( connection_struct conn,
uint32  file_attributes 
) [static]

nttrans.c306 行で定義されています。

参照先 connection_struct::case_preserveconnection_struct::case_sensitivecurrent_user::connsaved_case_preservesaved_case_sensitivesaved_short_case_preserveconnection_struct::short_case_preserve.

参照元 call_nt_transact_create()reply_ntcreate_and_X().

00307 {
00308         if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
00309                 return;
00310         }
00311 
00312         conn->case_sensitive = saved_case_sensitive;
00313         conn->case_preserve = saved_case_preserve;
00314         conn->short_case_preserve = saved_short_case_preserve;
00315 }

static int nt_open_pipe ( char *  fname,
connection_struct conn,
char *  inbuf,
char *  outbuf,
int *  ppnum 
) [static]

nttrans.c321 行で定義されています。

参照先 current_user::connknown_nt_pipesopen_rpc_pipe_p()smb_np_struct::pnumstore_pipe_opendb()strequal()current_user::vuid.

参照元 do_nt_transact_create_pipe()do_ntcreate_pipe_open().

00323 {
00324         smb_np_struct *p = NULL;
00325         uint16 vuid = SVAL(inbuf, smb_uid);
00326         int i;
00327  
00328         DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
00329     
00330         /* See if it is one we want to handle. */
00331 
00332         if (lp_disable_spoolss() && strequal(fname, "\\spoolss")) {
00333                 return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
00334         }
00335 
00336         for( i = 0; known_nt_pipes[i]; i++ ) {
00337                 if( strequal(fname,known_nt_pipes[i])) {
00338                         break;
00339                 }
00340         }
00341     
00342         if ( known_nt_pipes[i] == NULL ) {
00343                 return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
00344         }
00345     
00346         /* Strip \\ off the name. */
00347         fname++;
00348     
00349         DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
00350 
00351         p = open_rpc_pipe_p(fname, conn, vuid);
00352         if (!p) {
00353                 return(ERROR_DOS(ERRSRV,ERRnofids));
00354         }
00355 
00356         /* Add pipe to db */
00357         
00358         if ( !store_pipe_opendb( p ) ) {
00359                 DEBUG(3,("nt_open_pipe: failed to store %s pipe open.\n", fname));
00360         }
00361         
00362         *ppnum = p->pnum;
00363         return 0;
00364 }

static int do_ntcreate_pipe_open ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize 
) [static]

nttrans.c370 行で定義されています。

参照先 chain_reply()current_user::connflagsnt_open_pipe()set_message().

参照元 reply_ntcreate_and_X().

00372 {
00373         pstring fname;
00374         int ret;
00375         int pnum = -1;
00376         char *p = NULL;
00377         uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
00378 
00379         srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE);
00380 
00381         if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) {
00382                 return ret;
00383         }
00384 
00385         /*
00386          * Deal with pipe return.
00387          */  
00388 
00389         if (flags & EXTENDED_RESPONSE_REQUIRED) {
00390                 /* This is very strange. We
00391                  * return 50 words, but only set
00392                  * the wcnt to 42 ? It's definately
00393                  * what happens on the wire....
00394                  */
00395                 set_message(outbuf,50,0,True);
00396                 SCVAL(outbuf,smb_wct,42);
00397         } else {
00398                 set_message(outbuf,34,0,True);
00399         }
00400 
00401         p = outbuf + smb_vwv2;
00402         p++;
00403         SSVAL(p,0,pnum);
00404         p += 2;
00405         SIVAL(p,0,FILE_WAS_OPENED);
00406         p += 4;
00407         p += 32;
00408         SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
00409         p += 20;
00410         /* File type. */
00411         SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
00412         /* Device state. */
00413         SSVAL(p,2, 0x5FF); /* ? */
00414         p += 4;
00415 
00416         if (flags & EXTENDED_RESPONSE_REQUIRED) {
00417                 p += 25;
00418                 SIVAL(p,0,FILE_GENERIC_ALL);
00419                 /* 
00420                  * For pipes W2K3 seems to return
00421                  * 0x12019B next.
00422                  * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
00423                  */
00424                 SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
00425         }
00426 
00427         DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));
00428 
00429         return chain_reply(inbuf,outbuf,length,bufsize);
00430 }

int reply_ntcreate_and_X_quota ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize,
enum FAKE_FILE_TYPE  fake_file_type,
const char *  fname 
)

nttrans.c436 行で定義されています。

参照先 chain_reply()current_user::connfiles_struct::fnumfiles_struct::fsp_nameopen_fake_file()resultset_message()status.

参照元 reply_ntcreate_and_X().

00443 {
00444         int result;
00445         char *p;
00446         uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
00447         files_struct *fsp;
00448         NTSTATUS status;
00449 
00450         status = open_fake_file(conn, fake_file_type, fname, desired_access,
00451                                 &fsp);
00452 
00453         if (!NT_STATUS_IS_OK(status)) {
00454                 return ERROR_NT(status);
00455         }
00456 
00457         set_message(outbuf,34,0,True);
00458         
00459         p = outbuf + smb_vwv2;
00460         
00461         /* SCVAL(p,0,NO_OPLOCK_RETURN); */
00462         p++;
00463         SSVAL(p,0,fsp->fnum);
00464 
00465         DEBUG(5,("reply_ntcreate_and_X_quota: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
00466 
00467         result = chain_reply(inbuf,outbuf,length,bufsize);
00468         return result;
00469 }

int reply_ntcreate_and_X ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize 
)

nttrans.c475 行で定義されています。

参照先 can_delete_file_in_directory()can_write_to_file()chain_reply()check_name()close_file()files_struct::conndo_ntcreate_pipe_open()dos_filetime_timespec()ERROR_CLOSEFAKE_FILE_TYPE_NONEfile_fsp()flagsfiles_struct::fnumfiles_struct::fsp_nameget_allocation_size()get_atimespec()get_create_timespec()get_mtimespec()files_struct::initial_allocation_sizefiles_struct::is_directoryis_fake_file()is_ntfs_stream_name()open_directory()open_file_ntcreate()open_was_deferred()files_struct::oplock_typepermsput_long_date_timespec()reply_ntcreate_and_X_quota()resolve_dfspath()restore_case_semantics()resultset_message()set_posix_case_semantics()smb_roundup()srvstr_get_path()statusunix_convert()vfs_allocate_file_space().

00477 {  
00478         int result;
00479         pstring fname;
00480         uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
00481         uint32 access_mask = IVAL(inbuf,smb_ntcreate_DesiredAccess);
00482         uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
00483         uint32 new_file_attributes;
00484         uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess);
00485         uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
00486         uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions);
00487         uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid);
00488         /* Breakout the oplock request bits so we can set the
00489            reply bits separately. */
00490         int oplock_request = 0;
00491         uint32 fattr=0;
00492         SMB_OFF_T file_len = 0;
00493         SMB_STRUCT_STAT sbuf;
00494         int info = 0;
00495         files_struct *fsp = NULL;
00496         char *p = NULL;
00497         struct timespec c_timespec;
00498         struct timespec a_timespec;
00499         struct timespec m_timespec;
00500         BOOL extended_oplock_granted = False;
00501         NTSTATUS status;
00502 
00503         START_PROFILE(SMBntcreateX);
00504 
00505         DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x "
00506                   "file_attributes = 0x%x, share_access = 0x%x, "
00507                   "create_disposition = 0x%x create_options = 0x%x "
00508                   "root_dir_fid = 0x%x\n",
00509                         (unsigned int)flags,
00510                         (unsigned int)access_mask,
00511                         (unsigned int)file_attributes,
00512                         (unsigned int)share_access,
00513                         (unsigned int)create_disposition,
00514                         (unsigned int)create_options,
00515                         (unsigned int)root_dir_fid ));
00516 
00517         /*
00518          * If it's an IPC, use the pipe handler.
00519          */
00520 
00521         if (IS_IPC(conn)) {
00522                 if (lp_nt_pipe_support()) {
00523                         END_PROFILE(SMBntcreateX);
00524                         return do_ntcreate_pipe_open(conn,inbuf,outbuf,length,bufsize);
00525                 } else {
00526                         END_PROFILE(SMBntcreateX);
00527                         return(ERROR_DOS(ERRDOS,ERRnoaccess));
00528                 }
00529         }
00530 
00531         if (create_options & FILE_OPEN_BY_FILE_ID) {
00532                 END_PROFILE(SMBntcreateX);
00533                 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
00534         }
00535 
00536         /*
00537          * Get the file name.
00538          */
00539 
00540         if(root_dir_fid != 0) {
00541                 /*
00542                  * This filename is relative to a directory fid.
00543                  */
00544                 pstring rel_fname;
00545                 files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
00546 
00547                 if(!dir_fsp) {
00548                         END_PROFILE(SMBntcreateX);
00549                         return ERROR_DOS(ERRDOS,ERRbadfid);
00550                 }
00551 
00552                 if(!dir_fsp->is_directory) {
00553 
00554                         srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
00555                         if (!NT_STATUS_IS_OK(status)) {
00556                                 END_PROFILE(SMBntcreateX);
00557                                 return ERROR_NT(status);
00558                         }
00559 
00560                         /*
00561                          * Check to see if this is a mac fork of some kind.
00562                          */
00563 
00564                         if( is_ntfs_stream_name(fname)) {
00565                                 END_PROFILE(SMBntcreateX);
00566                                 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
00567                         }
00568 
00569                         /*
00570                           we need to handle the case when we get a
00571                           relative open relative to a file and the
00572                           pathname is blank - this is a reopen!
00573                           (hint from demyn plantenberg)
00574                         */
00575 
00576                         END_PROFILE(SMBntcreateX);
00577                         return(ERROR_DOS(ERRDOS,ERRbadfid));
00578                 }
00579 
00580                 /*
00581                  * Copy in the base directory name.
00582                  */
00583 
00584                 pstrcpy( fname, dir_fsp->fsp_name );
00585 
00586                 if (ISDOT(fname)) {
00587                         fname[0] = '\0';
00588                 } else {
00589                         size_t dir_name_len = strlen(fname);
00590                         /*
00591                          * Ensure it ends in a '\'.
00592                          */
00593 
00594                         if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
00595                                 pstrcat(fname, "/");
00596                         }
00597                 }
00598 
00599                 srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status);
00600                 if (!NT_STATUS_IS_OK(status)) {
00601                         END_PROFILE(SMBntcreateX);
00602                         return ERROR_NT(status);
00603                 }
00604                 pstrcat(fname, rel_fname);
00605         } else {
00606                 srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
00607                 if (!NT_STATUS_IS_OK(status)) {
00608                         END_PROFILE(SMBntcreateX);
00609                         return ERROR_NT(status);
00610                 }
00611 
00612                 /*
00613                  * Check to see if this is a mac fork of some kind.
00614                  */
00615 
00616                 if( is_ntfs_stream_name(fname)) {
00617                         enum FAKE_FILE_TYPE fake_file_type = is_fake_file(fname);
00618                         if (fake_file_type!=FAKE_FILE_TYPE_NONE) {
00619                                 /*
00620                                  * Here we go! support for changing the disk quotas --metze
00621                                  *
00622                                  * We need to fake up to open this MAGIC QUOTA file 
00623                                  * and return a valid FID.
00624                                  *
00625                                  * w2k close this file directly after openening
00626                                  * xp also tries a QUERY_FILE_INFO on the file and then close it
00627                                  */
00628                                 result = reply_ntcreate_and_X_quota(conn, inbuf, outbuf, length, bufsize,
00629                                                                 fake_file_type, fname);
00630                                 END_PROFILE(SMBntcreateX);
00631                                 return result;
00632                         } else {
00633                                 END_PROFILE(SMBntcreateX);
00634                                 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
00635                         }
00636                 }
00637         }
00638         
00639         /*
00640          * Now contruct the smb_open_mode value from the filename, 
00641          * desired access and the share access.
00642          */
00643         status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
00644         if (!NT_STATUS_IS_OK(status)) {
00645                 END_PROFILE(SMBntcreateX);
00646                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
00647                         return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
00648                 }
00649                 return ERROR_NT(status);
00650         }
00651 
00652         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
00653         if (oplock_request) {
00654                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
00655         }
00656 
00657         /*
00658          * Ordinary file or directory.
00659          */
00660                 
00661         /*
00662          * Check if POSIX semantics are wanted.
00663          */
00664                 
00665         new_file_attributes = set_posix_case_semantics(conn, file_attributes);
00666                 
00667         status = unix_convert(conn, fname, False, NULL, &sbuf);
00668         if (!NT_STATUS_IS_OK(status)) {
00669                 restore_case_semantics(conn, file_attributes);
00670                 END_PROFILE(SMBntcreateX);
00671                 return ERROR_NT(status);
00672         }
00673         /* All file access must go through check_name() */
00674         status = check_name(conn, fname);
00675         if (!NT_STATUS_IS_OK(status)) {
00676                 restore_case_semantics(conn, file_attributes);
00677                 END_PROFILE(SMBntcreateX);
00678                 return ERROR_NT(status);
00679         }
00680 
00681         /* This is the correct thing to do (check every time) but can_delete is
00682            expensive (it may have to read the parent directory permissions). So
00683            for now we're not doing it unless we have a strong hint the client
00684            is really going to delete this file. If the client is forcing FILE_CREATE
00685            let the filesystem take care of the permissions. */
00686 
00687         /* Setting FILE_SHARE_DELETE is the hint. */
00688 
00689         if (lp_acl_check_permissions(SNUM(conn))
00690             && (create_disposition != FILE_CREATE)
00691             && (share_access & FILE_SHARE_DELETE)
00692             && (access_mask & DELETE_ACCESS)) {
00693                 if ((dos_mode(conn, fname, &sbuf) & FILE_ATTRIBUTE_READONLY) ||
00694                                 !can_delete_file_in_directory(conn, fname)) {
00695                         restore_case_semantics(conn, file_attributes);
00696                         END_PROFILE(SMBntcreateX);
00697                         return ERROR_NT(NT_STATUS_ACCESS_DENIED);
00698                 }
00699         }
00700 
00701         /*
00702          * If it's a request for a directory open, deal with it separately.
00703          */
00704 
00705         if(create_options & FILE_DIRECTORY_FILE) {
00706 
00707                 /* Can't open a temp directory. IFS kit test. */
00708                 if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
00709                         END_PROFILE(SMBntcreateX);
00710                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
00711                 }
00712 
00713                 oplock_request = 0;
00714                 status = open_directory(conn, fname, &sbuf,
00715                                         access_mask,
00716                                         share_access,
00717                                         create_disposition,
00718                                         create_options,
00719                                         new_file_attributes,
00720                                         &info, &fsp);
00721         } else {
00722 
00723                 /*
00724                  * Ordinary file case.
00725                  */
00726 
00727                 /* NB. We have a potential bug here. If we
00728                  * cause an oplock break to ourselves, then we
00729                  * could end up processing filename related
00730                  * SMB requests whilst we await the oplock
00731                  * break response. As we may have changed the
00732                  * filename case semantics to be POSIX-like,
00733                  * this could mean a filename request could
00734                  * fail when it should succeed. This is a rare
00735                  * condition, but eventually we must arrange
00736                  * to restore the correct case semantics
00737                  * before issuing an oplock break request to
00738                  * our client. JRA.  */
00739 
00740                 status = open_file_ntcreate(conn,fname,&sbuf,
00741                                         access_mask,
00742                                         share_access,
00743                                         create_disposition,
00744                                         create_options,
00745                                         new_file_attributes,
00746                                         oplock_request,
00747                                         &info, &fsp);
00748 
00749                 if (!NT_STATUS_IS_OK(status)) {
00750                         /* We cheat here. There are two cases we
00751                          * care about. One is a directory rename,
00752                          * where the NT client will attempt to
00753                          * open the source directory for
00754                          * DELETE access. Note that when the
00755                          * NT client does this it does *not*
00756                          * set the directory bit in the
00757                          * request packet. This is translated
00758                          * into a read/write open
00759                          * request. POSIX states that any open
00760                          * for write request on a directory
00761                          * will generate an EISDIR error, so
00762                          * we can catch this here and open a
00763                          * pseudo handle that is flagged as a
00764                          * directory. The second is an open
00765                          * for a permissions read only, which
00766                          * we handle in the open_file_stat case. JRA.
00767                          */
00768 
00769                         if (NT_STATUS_EQUAL(status,
00770                                             NT_STATUS_FILE_IS_A_DIRECTORY)) {
00771 
00772                                 /*
00773                                  * Fail the open if it was explicitly a non-directory file.
00774                                  */
00775 
00776                                 if (create_options & FILE_NON_DIRECTORY_FILE) {
00777                                         restore_case_semantics(conn, file_attributes);
00778                                         END_PROFILE(SMBntcreateX);
00779                                         return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
00780                                 }
00781 
00782                                 oplock_request = 0;
00783                                 status = open_directory(conn, fname, &sbuf,
00784                                                         access_mask,
00785                                                         share_access,
00786                                                         create_disposition,
00787                                                         create_options,
00788                                                         new_file_attributes,
00789                                                         &info, &fsp);
00790 
00791                         }
00792                 }
00793         }
00794 
00795         restore_case_semantics(conn, file_attributes);
00796 
00797         if(!NT_STATUS_IS_OK(status)) {
00798                 END_PROFILE(SMBntcreateX);
00799 
00800                 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
00801                         /* We have re-scheduled this call. */
00802                         return -1;
00803                 }
00804 
00805                 return ERROR_OPEN(status);
00806         }
00807 
00808         file_len = sbuf.st_size;
00809         fattr = dos_mode(conn,fname,&sbuf);
00810         if(fattr == 0) {
00811                 fattr = FILE_ATTRIBUTE_NORMAL;
00812         }
00813         if (!fsp->is_directory && (fattr & aDIR)) {
00814                 close_file(fsp,ERROR_CLOSE);
00815                 END_PROFILE(SMBntcreateX);
00816                 return ERROR_DOS(ERRDOS,ERRnoaccess);
00817         } 
00818         
00819         /* Save the requested allocation size. */
00820         if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
00821                 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize);
00822 #ifdef LARGE_SMB_OFF_T
00823                 allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
00824 #endif
00825                 if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
00826                         fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
00827                         if (fsp->is_directory) {
00828                                 close_file(fsp,ERROR_CLOSE);
00829                                 END_PROFILE(SMBntcreateX);
00830                                 /* Can't set allocation size on a directory. */
00831                                 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
00832                         }
00833                         if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
00834                                 close_file(fsp,ERROR_CLOSE);
00835                                 END_PROFILE(SMBntcreateX);
00836                                 return ERROR_NT(NT_STATUS_DISK_FULL);
00837                         }
00838                 } else {
00839                         fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)file_len);
00840                 }
00841         }
00842 
00843         /* 
00844          * If the caller set the extended oplock request bit
00845          * and we granted one (by whatever means) - set the
00846          * correct bit for extended oplock reply.
00847          */
00848 
00849         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
00850                 extended_oplock_granted = True;
00851         }
00852 
00853         if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
00854                 extended_oplock_granted = True;
00855         }
00856 
00857         if (flags & EXTENDED_RESPONSE_REQUIRED) {
00858                 /* This is very strange. We
00859                  * return 50 words, but only set
00860                  * the wcnt to 42 ? It's definately
00861                  * what happens on the wire....
00862                  */
00863                 set_message(outbuf,50,0,True);
00864                 SCVAL(outbuf,smb_wct,42);
00865         } else {
00866                 set_message(outbuf,34,0,True);
00867         }
00868 
00869         p = outbuf + smb_vwv2;
00870         
00871         /*
00872          * Currently as we don't support level II oplocks we just report
00873          * exclusive & batch here.
00874          */
00875 
00876         if (extended_oplock_granted) {
00877                 if (flags & REQUEST_BATCH_OPLOCK) {
00878                         SCVAL(p,0, BATCH_OPLOCK_RETURN);
00879                 } else {
00880                         SCVAL(p,0, EXCLUSIVE_OPLOCK_RETURN);
00881                 }
00882         } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
00883                 SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
00884         } else {
00885                 SCVAL(p,0,NO_OPLOCK_RETURN);
00886         }
00887         
00888         p++;
00889         SSVAL(p,0,fsp->fnum);
00890         p += 2;
00891         if ((create_disposition == FILE_SUPERSEDE) && (info == FILE_WAS_OVERWRITTEN)) {
00892                 SIVAL(p,0,FILE_WAS_SUPERSEDED);
00893         } else {
00894                 SIVAL(p,0,info);
00895         }
00896         p += 4;
00897 
00898         /* Create time. */
00899         c_timespec = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
00900         a_timespec = get_atimespec(&sbuf);
00901         m_timespec = get_mtimespec(&sbuf);
00902 
00903         if (lp_dos_filetime_resolution(SNUM(conn))) {
00904                 dos_filetime_timespec(&c_timespec);
00905                 dos_filetime_timespec(&a_timespec);
00906                 dos_filetime_timespec(&m_timespec);
00907         }
00908 
00909         put_long_date_timespec(p, c_timespec); /* create time. */
00910         p += 8;
00911         put_long_date_timespec(p, a_timespec); /* access time */
00912         p += 8;
00913         put_long_date_timespec(p, m_timespec); /* write time */
00914         p += 8;
00915         put_long_date_timespec(p, m_timespec); /* change time */
00916         p += 8;
00917         SIVAL(p,0,fattr); /* File Attributes. */
00918         p += 4;
00919         SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
00920         p += 8;
00921         SOFF_T(p,0,file_len);
00922         p += 8;
00923         if (flags & EXTENDED_RESPONSE_REQUIRED) {
00924                 SSVAL(p,2,0x7);
00925         }
00926         p += 4;
00927         SCVAL(p,0,fsp->is_directory ? 1 : 0);
00928 
00929         if (flags & EXTENDED_RESPONSE_REQUIRED) {
00930                 uint32 perms = 0;
00931                 p += 25;
00932                 if (fsp->is_directory || can_write_to_file(conn, fname, &sbuf)) {
00933                         perms = FILE_GENERIC_ALL;
00934                 } else {
00935                         perms = FILE_GENERIC_READ|FILE_EXECUTE;
00936                 }
00937                 SIVAL(p,0,perms);
00938         }
00939 
00940         DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
00941 
00942         result = chain_reply(inbuf,outbuf,length,bufsize);
00943         END_PROFILE(SMBntcreateX);
00944         return result;
00945 }

static int do_nt_transact_create_pipe ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize,
uint16 **  ppsetup,
uint32  setup_count,
char **  ppparams,
uint32  parameter_count,
char **  ppdata,
uint32  data_count 
) [static]

nttrans.c951 行で定義されています。

参照先 flagsnt_open_pipe()nttrans_realloc()send_nt_replies()srvstr_get_path()status.

参照元 call_nt_transact_create().

00955 {
00956         pstring fname;
00957         char *params = *ppparams;
00958         int ret;
00959         int pnum = -1;
00960         char *p = NULL;
00961         NTSTATUS status;
00962         size_t param_len;
00963         uint32 flags;
00964 
00965         /*
00966          * Ensure minimum number of parameters sent.
00967          */
00968 
00969         if(parameter_count < 54) {
00970                 DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));
00971                 return ERROR_DOS(ERRDOS,ERRnoaccess);
00972         }
00973 
00974         flags = IVAL(params,0);
00975 
00976         srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
00977         if (!NT_STATUS_IS_OK(status)) {
00978                 return ERROR_NT(status);
00979         }
00980 
00981         if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) {
00982                 return ret;
00983         }
00984         
00985         /* Realloc the size of parameters and data we will return */
00986         if (flags & EXTENDED_RESPONSE_REQUIRED) {
00987                 /* Extended response is 32 more byyes. */
00988                 param_len = 101;
00989         } else {
00990                 param_len = 69;
00991         }
00992         params = nttrans_realloc(ppparams, param_len);
00993         if(params == NULL) {
00994                 return ERROR_DOS(ERRDOS,ERRnomem);
00995         }
00996         
00997         p = params;
00998         SCVAL(p,0,NO_OPLOCK_RETURN);
00999         
01000         p += 2;
01001         SSVAL(p,0,pnum);
01002         p += 2;
01003         SIVAL(p,0,FILE_WAS_OPENED);
01004         p += 8;
01005         
01006         p += 32;
01007         SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
01008         p += 20;
01009         /* File type. */
01010         SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
01011         /* Device state. */
01012         SSVAL(p,2, 0x5FF); /* ? */
01013         p += 4;
01014         
01015         if (flags & EXTENDED_RESPONSE_REQUIRED) {
01016                 p += 25;
01017                 SIVAL(p,0,FILE_GENERIC_ALL);
01018                 /* 
01019                  * For pipes W2K3 seems to return
01020                  * 0x12019B next.
01021                  * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
01022                  */
01023                 SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
01024         }
01025 
01026         DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
01027         
01028         /* Send the required number of replies */
01029         send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, param_len, *ppdata, 0);
01030         
01031         return -1;
01032 }

static NTSTATUS set_sd ( files_struct fsp,
char *  data,
uint32  sd_len,
uint32  security_info_sent 
) [static]

nttrans.c1038 行で定義されています。

参照先 files_struct::connsecurity_descriptor_info::daclfd_handle::fdfiles_struct::fhsecurity_descriptor_info::group_sidsecurity_descriptor_info::owner_sidprs_init()security_descriptor_info::saclsec_io_desc()talloc_init().

参照元 call_nt_transact_create()call_nt_transact_set_security_desc().

01039 {
01040         prs_struct pd;
01041         SEC_DESC *psd = NULL;
01042         TALLOC_CTX *mem_ctx;
01043         BOOL ret;
01044         
01045         if (sd_len == 0 || !lp_nt_acl_support(SNUM(fsp->conn))) {
01046                 return NT_STATUS_OK;
01047         }
01048 
01049         /*
01050          * Init the parse struct we will unmarshall from.
01051          */
01052 
01053         if ((mem_ctx = talloc_init("set_sd")) == NULL) {
01054                 DEBUG(0,("set_sd: talloc_init failed.\n"));
01055                 return NT_STATUS_NO_MEMORY;
01056         }
01057 
01058         prs_init(&pd, 0, mem_ctx, UNMARSHALL);
01059 
01060         /*
01061          * Setup the prs_struct to point at the memory we just
01062          * allocated.
01063          */
01064         
01065         prs_give_memory( &pd, data, sd_len, False);
01066 
01067         /*
01068          * Finally, unmarshall from the data buffer.
01069          */
01070 
01071         if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
01072                 DEBUG(0,("set_sd: Error in unmarshalling security descriptor.\n"));
01073                 /*
01074                  * Return access denied for want of a better error message..
01075                  */ 
01076                 talloc_destroy(mem_ctx);
01077                 return NT_STATUS_NO_MEMORY;
01078         }
01079         
01080         if (psd->owner_sid==0) {
01081                 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
01082         }
01083         if (psd->group_sid==0) {
01084                 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
01085         }
01086         if (psd->sacl==0) {
01087                 security_info_sent &= ~SACL_SECURITY_INFORMATION;
01088         }
01089         if (psd->dacl==0) {
01090                 security_info_sent &= ~DACL_SECURITY_INFORMATION;
01091         }
01092         
01093         ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd);
01094         
01095         if (!ret) {
01096                 talloc_destroy(mem_ctx);
01097                 return NT_STATUS_ACCESS_DENIED;
01098         }
01099         
01100         talloc_destroy(mem_ctx);
01101         
01102         return NT_STATUS_OK;
01103 }

static struct ea_list* read_nttrans_ea_list ( TALLOC_CTX ctx,
const char *  pdata,
size_t  data_size 
) [static]

nttrans.c1109 行で定義されています。

参照先 read_ea_list_entry().

参照元 call_nt_transact_create().

01110 {
01111         struct ea_list *ea_list_head = NULL;
01112         size_t offset = 0;
01113 
01114         if (data_size < 4) {
01115                 return NULL;
01116         }
01117 
01118         while (offset + 4 <= data_size) {
01119                 size_t next_offset = IVAL(pdata,offset);
01120                 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset + 4, data_size - offset - 4, NULL);
01121 
01122                 if (!eal) {
01123                         return NULL;
01124                 }
01125 
01126                 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
01127                 if (next_offset == 0) {
01128                         break;
01129                 }
01130                 offset += next_offset;
01131         }
01132                                                                                                                              
01133         return ea_list_head;
01134 }

static int call_nt_transact_create ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize,
uint16 **  ppsetup,
uint32  setup_count,
char **  ppparams,
uint32  parameter_count,
char **  ppdata,
uint32  data_count,
uint32  max_data_count 
) [static]

nttrans.c1140 行で定義されています。

参照先 files_struct::access_maskcan_delete_file_in_directory()can_write_to_file()check_name()close_file()files_struct::connctxdo_nt_transact_create_pipe()dos_filetime_timespec()ERROR_CLOSEfile_fsp()flagsfiles_struct::fnumfiles_struct::fsp_nameget_allocation_size()get_atimespec()get_create_timespec()get_mtimespec()files_struct::initial_allocation_sizefiles_struct::is_directoryis_ntfs_stream_name()nttrans_realloc()open_directory()open_file_ntcreate()open_was_deferred()files_struct::oplock_typepermsput_long_date_timespec()read_nttrans_ea_list()resolve_dfspath()restore_case_semantics()send_nt_replies()set_ea()set_posix_case_semantics()set_sd()smb_roundup()srvstr_get_path()statustmp_talloc_ctx()unix_convert()vfs_allocate_file_space().

参照元 handle_nttrans().

01144 {
01145         pstring fname;
01146         char *params = *ppparams;
01147         char *data = *ppdata;
01148         /* Breakout the oplock request bits so we can set the reply bits separately. */
01149         int oplock_request = 0;
01150         uint32 fattr=0;
01151         SMB_OFF_T file_len = 0;
01152         SMB_STRUCT_STAT sbuf;
01153         int info = 0;
01154         files_struct *fsp = NULL;
01155         char *p = NULL;
01156         BOOL extended_oplock_granted = False;
01157         uint32 flags;
01158         uint32 access_mask;
01159         uint32 file_attributes;
01160         uint32 new_file_attributes;
01161         uint32 share_access;
01162         uint32 create_disposition;
01163         uint32 create_options;
01164         uint32 sd_len;
01165         uint32 ea_len;
01166         uint16 root_dir_fid;
01167         struct timespec c_timespec;
01168         struct timespec a_timespec;
01169         struct timespec m_timespec;
01170         struct ea_list *ea_list = NULL;
01171         TALLOC_CTX *ctx = NULL;
01172         char *pdata = NULL;
01173         NTSTATUS status;
01174         size_t param_len;
01175 
01176         DEBUG(5,("call_nt_transact_create\n"));
01177 
01178         /*
01179          * If it's an IPC, use the pipe handler.
01180          */
01181 
01182         if (IS_IPC(conn)) {
01183                 if (lp_nt_pipe_support()) {
01184                         return do_nt_transact_create_pipe(conn, inbuf, outbuf, length, 
01185                                         bufsize,
01186                                         ppsetup, setup_count,
01187                                         ppparams, parameter_count,
01188                                         ppdata, data_count);
01189                 } else {
01190                         return ERROR_DOS(ERRDOS,ERRnoaccess);
01191                 }
01192         }
01193 
01194         /*
01195          * Ensure minimum number of parameters sent.
01196          */
01197 
01198         if(parameter_count < 54) {
01199                 DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
01200                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
01201         }
01202 
01203         flags = IVAL(params,0);
01204         access_mask = IVAL(params,8);
01205         file_attributes = IVAL(params,20);
01206         share_access = IVAL(params,24);
01207         create_disposition = IVAL(params,28);
01208         create_options = IVAL(params,32);
01209         sd_len = IVAL(params,36);
01210         ea_len = IVAL(params,40);
01211         root_dir_fid = (uint16)IVAL(params,4);
01212 
01213         /* Ensure the data_len is correct for the sd and ea values given. */
01214         if ((ea_len + sd_len > data_count) ||
01215                         (ea_len > data_count) || (sd_len > data_count) ||
01216                         (ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {
01217                 DEBUG(10,("call_nt_transact_create - ea_len = %u, sd_len = %u, data_count = %u\n",
01218                         (unsigned int)ea_len, (unsigned int)sd_len, (unsigned int)data_count ));
01219                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
01220         }
01221 
01222         if (ea_len) {
01223                 if (!lp_ea_support(SNUM(conn))) {
01224                         DEBUG(10,("call_nt_transact_create - ea_len = %u but EA's not supported.\n",
01225                                 (unsigned int)ea_len ));
01226                         return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
01227                 }
01228 
01229                 if (ea_len < 10) {
01230                         DEBUG(10,("call_nt_transact_create - ea_len = %u - too small (should be more than 10)\n",
01231                                 (unsigned int)ea_len ));
01232                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
01233                 }
01234         }
01235 
01236         if (create_options & FILE_OPEN_BY_FILE_ID) {
01237                 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
01238         }
01239 
01240         /*
01241          * Get the file name.
01242          */
01243 
01244         if(root_dir_fid != 0) {
01245                 /*
01246                  * This filename is relative to a directory fid.
01247                  */
01248                 files_struct *dir_fsp = file_fsp(params,4);
01249 
01250                 if(!dir_fsp) {
01251                         return ERROR_DOS(ERRDOS,ERRbadfid);
01252                 }
01253 
01254                 if(!dir_fsp->is_directory) {
01255                         srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
01256                         if (!NT_STATUS_IS_OK(status)) {
01257                                 return ERROR_NT(status);
01258                         }
01259 
01260                         /*
01261                          * Check to see if this is a mac fork of some kind.
01262                          */
01263 
01264                         if( is_ntfs_stream_name(fname)) {
01265                                 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
01266                         }
01267 
01268                         return ERROR_DOS(ERRDOS,ERRbadfid);
01269                 }
01270 
01271                 /*
01272                  * Copy in the base directory name.
01273                  */
01274 
01275                 pstrcpy( fname, dir_fsp->fsp_name );
01276 
01277                 if (ISDOT(fname)) {
01278                         fname[0] = '\0';
01279                 } else {
01280                         size_t dir_name_len = strlen(fname);
01281                         /*
01282                          * Ensure it ends in a '\'.
01283                          */
01284 
01285                         if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
01286                                 pstrcat(fname, "/");
01287                         }
01288                 }
01289 
01290                 {
01291                         pstring tmpname;
01292                         srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status);
01293                         if (!NT_STATUS_IS_OK(status)) {
01294                                 return ERROR_NT(status);
01295                         }
01296                         pstrcat(fname, tmpname);
01297                 }
01298         } else {
01299                 srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
01300                 if (!NT_STATUS_IS_OK(status)) {
01301                         return ERROR_NT(status);
01302                 }
01303 
01304                 /*
01305                  * Check to see if this is a mac fork of some kind.
01306                  */
01307 
01308                 if( is_ntfs_stream_name(fname)) {
01309                         return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
01310                 }
01311         }
01312 
01313         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
01314         if (oplock_request) {
01315                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
01316         }
01317 
01318         /*
01319          * Ordinary file or directory.
01320          */
01321                 
01322         /*
01323          * Check if POSIX semantics are wanted.
01324          */
01325                 
01326         new_file_attributes = set_posix_case_semantics(conn, file_attributes);
01327     
01328         status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
01329         if (!NT_STATUS_IS_OK(status)) {
01330                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
01331                         return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
01332                 }
01333                 return ERROR_NT(status);
01334         }
01335 
01336         status = unix_convert(conn, fname, False, NULL, &sbuf);
01337         if (!NT_STATUS_IS_OK(status)) {
01338                 restore_case_semantics(conn, file_attributes);
01339                 return ERROR_NT(status);
01340         }
01341         /* All file access must go through check_name() */
01342         status = check_name(conn, fname);
01343         if (!NT_STATUS_IS_OK(status)) {
01344                 restore_case_semantics(conn, file_attributes);
01345                 return ERROR_NT(status);
01346         }
01347 
01348         /* This is the correct thing to do (check every time) but can_delete is
01349            expensive (it may have to read the parent directory permissions). So
01350            for now we're not doing it unless we have a strong hint the client
01351            is really going to delete this file. If the client is forcing FILE_CREATE
01352            let the filesystem take care of the permissions. */
01353 
01354         /* Setting FILE_SHARE_DELETE is the hint. */
01355 
01356         if (lp_acl_check_permissions(SNUM(conn))
01357             && (create_disposition != FILE_CREATE)
01358             && (share_access & FILE_SHARE_DELETE)
01359             && (access_mask & DELETE_ACCESS)) {
01360                 if ((dos_mode(conn, fname, &sbuf) & FILE_ATTRIBUTE_READONLY) ||
01361                                 !can_delete_file_in_directory(conn, fname)) {
01362                         restore_case_semantics(conn, file_attributes);
01363                         return ERROR_NT(NT_STATUS_ACCESS_DENIED);
01364                 }
01365         }
01366 
01367         if (ea_len) {
01368                 pdata = data + sd_len;
01369 
01370                 /* We have already checked that ea_len <= data_count here. */
01371                 ea_list = read_nttrans_ea_list(tmp_talloc_ctx(), pdata,
01372                                                ea_len);
01373                 if (!ea_list ) {
01374                         restore_case_semantics(conn, file_attributes);
01375                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
01376                 }
01377         }
01378 
01379         /*
01380          * If it's a request for a directory open, deal with it separately.
01381          */
01382 
01383         if(create_options & FILE_DIRECTORY_FILE) {
01384 
01385                 /* Can't open a temp directory. IFS kit test. */
01386                 if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
01387                         restore_case_semantics(conn, file_attributes);
01388                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
01389                 }
01390 
01391                 /*
01392                  * We will get a create directory here if the Win32
01393                  * app specified a security descriptor in the 
01394                  * CreateDirectory() call.
01395                  */
01396 
01397                 oplock_request = 0;
01398                 status = open_directory(conn, fname, &sbuf,
01399                                         access_mask,
01400                                         share_access,
01401                                         create_disposition,
01402                                         create_options,
01403                                         new_file_attributes,
01404                                         &info, &fsp);
01405         } else {
01406 
01407                 /*
01408                  * Ordinary file case.
01409                  */
01410 
01411                 status = open_file_ntcreate(conn,fname,&sbuf,
01412                                         access_mask,
01413                                         share_access,
01414                                         create_disposition,
01415                                         create_options,
01416                                         new_file_attributes,
01417                                         oplock_request,
01418                                         &info, &fsp);
01419 
01420                 if (!NT_STATUS_IS_OK(status)) {
01421                         if (NT_STATUS_EQUAL(status,
01422                                             NT_STATUS_FILE_IS_A_DIRECTORY)) {
01423 
01424                                 /*
01425                                  * Fail the open if it was explicitly a non-directory file.
01426                                  */
01427 
01428                                 if (create_options & FILE_NON_DIRECTORY_FILE) {
01429                                         restore_case_semantics(conn, file_attributes);
01430                                         return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
01431                                 }
01432 
01433                                 oplock_request = 0;
01434                                 status = open_directory(conn, fname, &sbuf,
01435                                                         access_mask,
01436                                                         share_access,
01437                                                         create_disposition,
01438                                                         create_options,
01439                                                         new_file_attributes,
01440                                                         &info, &fsp);
01441                         }
01442                 }
01443         }
01444 
01445         restore_case_semantics(conn, file_attributes);
01446         if(!NT_STATUS_IS_OK(status)) {
01447 
01448                 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
01449                         /* We have re-scheduled this call. */
01450                         return -1;
01451                 }
01452 
01453                 return ERROR_OPEN(status);
01454         }
01455 
01456         /*
01457          * According to the MS documentation, the only time the security
01458          * descriptor is applied to the opened file is iff we *created* the
01459          * file; an existing file stays the same.
01460          *
01461          * Also, it seems (from observation) that you can open the file with
01462          * any access mask but you can still write the sd. We need to override
01463          * the granted access before we call set_sd
01464          * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
01465          */
01466 
01467         if (lp_nt_acl_support(SNUM(conn)) && sd_len && info == FILE_WAS_CREATED) {
01468                 uint32 saved_access_mask = fsp->access_mask;
01469 
01470                 /* We have already checked that sd_len <= data_count here. */
01471 
01472                 fsp->access_mask = FILE_GENERIC_ALL;
01473 
01474                 status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION);
01475                 if (!NT_STATUS_IS_OK(status)) {
01476                         talloc_destroy(ctx);
01477                         close_file(fsp,ERROR_CLOSE);
01478                         restore_case_semantics(conn, file_attributes);
01479                         return ERROR_NT(status);
01480                 }
01481                 fsp->access_mask = saved_access_mask;
01482         }
01483         
01484         if (ea_len && (info == FILE_WAS_CREATED)) {
01485                 status = set_ea(conn, fsp, fname, ea_list);
01486                 if (!NT_STATUS_IS_OK(status)) {
01487                         close_file(fsp,ERROR_CLOSE);
01488                         restore_case_semantics(conn, file_attributes);
01489                         return ERROR_NT(status);
01490                 }
01491         }
01492 
01493         restore_case_semantics(conn, file_attributes);
01494 
01495         file_len = sbuf.st_size;
01496         fattr = dos_mode(conn,fname,&sbuf);
01497         if(fattr == 0) {
01498                 fattr = FILE_ATTRIBUTE_NORMAL;
01499         }
01500         if (!fsp->is_directory && (fattr & aDIR)) {
01501                 close_file(fsp,ERROR_CLOSE);
01502                 return ERROR_DOS(ERRDOS,ERRnoaccess);
01503         } 
01504         
01505         /* Save the requested allocation size. */
01506         if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
01507                 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(params,12);
01508 #ifdef LARGE_SMB_OFF_T
01509                 allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
01510 #endif
01511                 if (allocation_size && (allocation_size > file_len)) {
01512                         fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
01513                         if (fsp->is_directory) {
01514                                 close_file(fsp,ERROR_CLOSE);
01515                                 /* Can't set allocation size on a directory. */
01516                                 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
01517                         }
01518                         if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
01519                                 close_file(fsp,ERROR_CLOSE);
01520                                 return ERROR_NT(NT_STATUS_DISK_FULL);
01521                         }
01522                 } else {
01523                         fsp->initial_allocation_size = smb_roundup(fsp->conn, (SMB_BIG_UINT)file_len);
01524                 }
01525         }
01526 
01527         /* 
01528          * If the caller set the extended oplock request bit
01529          * and we granted one (by whatever means) - set the
01530          * correct bit for extended oplock reply.
01531          */
01532 
01533         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
01534                 extended_oplock_granted = True;
01535         }
01536 
01537         if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
01538                 extended_oplock_granted = True;
01539         }
01540 
01541         /* Realloc the size of parameters and data we will return */
01542         if (flags & EXTENDED_RESPONSE_REQUIRED) {
01543                 /* Extended response is 32 more byyes. */
01544                 param_len = 101;
01545         } else {
01546                 param_len = 69;
01547         }
01548         params = nttrans_realloc(ppparams, param_len);
01549         if(params == NULL) {
01550                 return ERROR_DOS(ERRDOS,ERRnomem);
01551         }
01552 
01553         p = params;
01554         if (extended_oplock_granted) {
01555                 if (flags & REQUEST_BATCH_OPLOCK) {
01556                         SCVAL(p,0, BATCH_OPLOCK_RETURN);
01557                 } else {
01558                         SCVAL(p,0, EXCLUSIVE_OPLOCK_RETURN);
01559                 }
01560         } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
01561                 SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
01562         } else {
01563                 SCVAL(p,0,NO_OPLOCK_RETURN);
01564         }
01565         
01566         p += 2;
01567         SSVAL(p,0,fsp->fnum);
01568         p += 2;
01569         if ((create_disposition == FILE_SUPERSEDE) && (info == FILE_WAS_OVERWRITTEN)) {
01570                 SIVAL(p,0,FILE_WAS_SUPERSEDED);
01571         } else {
01572                 SIVAL(p,0,info);
01573         }
01574         p += 8;
01575 
01576         /* Create time. */
01577         c_timespec = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
01578         a_timespec = get_atimespec(&sbuf);
01579         m_timespec = get_mtimespec(&sbuf);
01580 
01581         if (lp_dos_filetime_resolution(SNUM(conn))) {
01582                 dos_filetime_timespec(&c_timespec);
01583                 dos_filetime_timespec(&a_timespec);
01584                 dos_filetime_timespec(&m_timespec);
01585         }
01586 
01587         put_long_date_timespec(p, c_timespec); /* create time. */
01588         p += 8;
01589         put_long_date_timespec(p, a_timespec); /* access time */
01590         p += 8;
01591         put_long_date_timespec(p, m_timespec); /* write time */
01592         p += 8;
01593         put_long_date_timespec(p, m_timespec); /* change time */
01594         p += 8;
01595         SIVAL(p,0,fattr); /* File Attributes. */
01596         p += 4;
01597         SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
01598         p += 8;
01599         SOFF_T(p,0,file_len);
01600         p += 8;
01601         if (flags & EXTENDED_RESPONSE_REQUIRED) {
01602                 SSVAL(p,2,0x7);
01603         }
01604         p += 4;
01605         SCVAL(p,0,fsp->is_directory ? 1 : 0);
01606 
01607         if (flags & EXTENDED_RESPONSE_REQUIRED) {
01608                 uint32 perms = 0;
01609                 p += 25;
01610                 if (fsp->is_directory || can_write_to_file(conn, fname, &sbuf)) {
01611                         perms = FILE_GENERIC_ALL;
01612                 } else {
01613                         perms = FILE_GENERIC_READ|FILE_EXECUTE;
01614                 }
01615                 SIVAL(p,0,perms);
01616         }
01617 
01618         DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
01619 
01620         /* Send the required number of replies */
01621         send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, param_len, *ppdata, 0);
01622 
01623         return -1;
01624 }

int reply_ntcancel ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize 
)

nttrans.c1631 行で定義されています。

参照先 remove_pending_change_notify_requests_by_mid()remove_pending_lock_requests_by_mid()srv_cancel_sign_response().

01633 {
01634         /*
01635          * Go through and cancel any pending change notifies.
01636          */
01637         
01638         int mid = SVAL(inbuf,smb_mid);
01639         START_PROFILE(SMBntcancel);
01640         remove_pending_change_notify_requests_by_mid(mid);
01641         remove_pending_lock_requests_by_mid(mid);
01642         srv_cancel_sign_response(mid);
01643         
01644         DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));
01645 
01646         END_PROFILE(SMBntcancel);
01647         return(-1);
01648 }

static NTSTATUS copy_internals ( connection_struct conn,
char *  oldname,
char *  newname,
uint32  attrs 
) [static]

nttrans.c1654 行で定義されています。

参照先 check_name()close_file()ERROR_CLOSEfsp_set_pending_modtime()get_mtimespec()NORMAL_CLOSEnt_errstr()open_file_ntcreate()parent_dirname()reduce_name()statusunix_convert()vfs_transfer_file().

参照元 reply_ntrename().

01655 {
01656         SMB_STRUCT_STAT sbuf1, sbuf2;
01657         pstring last_component_oldname;
01658         pstring last_component_newname;
01659         files_struct *fsp1,*fsp2;
01660         uint32 fattr;
01661         int info;
01662         SMB_OFF_T ret=-1;
01663         NTSTATUS status = NT_STATUS_OK;
01664 
01665         ZERO_STRUCT(sbuf1);
01666         ZERO_STRUCT(sbuf2);
01667 
01668         if (!CAN_WRITE(conn)) {
01669                 return NT_STATUS_MEDIA_WRITE_PROTECTED;
01670         }
01671 
01672         status = unix_convert(conn, oldname, False, last_component_oldname, &sbuf1);
01673         if (!NT_STATUS_IS_OK(status)) {
01674                 return status;
01675         }
01676 
01677         status = check_name(conn, oldname);
01678         if (!NT_STATUS_IS_OK(status)) {
01679                 return status;
01680         }
01681 
01682         /* Source must already exist. */
01683         if (!VALID_STAT(sbuf1)) {
01684                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
01685         }
01686         /* Ensure attributes match. */
01687         fattr = dos_mode(conn,oldname,&sbuf1);
01688         if ((fattr & ~attrs) & (aHIDDEN | aSYSTEM)) {
01689                 return NT_STATUS_NO_SUCH_FILE;
01690         }
01691 
01692         status = unix_convert(conn, newname, False, last_component_newname, &sbuf2);
01693         if (!NT_STATUS_IS_OK(status)) {
01694                 return status;
01695         }
01696 
01697         status = check_name(conn, newname);
01698         if (!NT_STATUS_IS_OK(status)) {
01699                 return status;
01700         }
01701 
01702         /* Disallow if newname already exists. */
01703         if (VALID_STAT(sbuf2)) {
01704                 return NT_STATUS_OBJECT_NAME_COLLISION;
01705         }
01706 
01707         /* No links from a directory. */
01708         if (S_ISDIR(sbuf1.st_mode)) {
01709                 return NT_STATUS_FILE_IS_A_DIRECTORY;
01710         }
01711 
01712         /* Ensure this is within the share. */
01713         status = reduce_name(conn, oldname);
01714         if (!NT_STATUS_IS_OK(status)) {
01715                 return status;
01716         }
01717 
01718         DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname));
01719 
01720         status = open_file_ntcreate(conn,oldname,&sbuf1,
01721                         FILE_READ_DATA, /* Read-only. */
01722                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
01723                         FILE_OPEN,
01724                         0, /* No create options. */
01725                         FILE_ATTRIBUTE_NORMAL,
01726                         NO_OPLOCK,
01727                         &info, &fsp1);
01728 
01729         if (!NT_STATUS_IS_OK(status)) {
01730                 return status;
01731         }
01732 
01733         status = open_file_ntcreate(conn,newname,&sbuf2,
01734                         FILE_WRITE_DATA, /* Read-only. */
01735                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
01736                         FILE_CREATE,
01737                         0, /* No create options. */
01738                         fattr,
01739                         NO_OPLOCK,
01740                         &info, &fsp2);
01741 
01742         if (!NT_STATUS_IS_OK(status)) {
01743                 close_file(fsp1,ERROR_CLOSE);
01744                 return status;
01745         }
01746 
01747         if (sbuf1.st_size) {
01748                 ret = vfs_transfer_file(fsp1, fsp2, sbuf1.st_size);
01749         }
01750 
01751         /*
01752          * As we are opening fsp1 read-only we only expect
01753          * an error on close on fsp2 if we are out of space.
01754          * Thus we don't look at the error return from the
01755          * close of fsp1.
01756          */
01757         close_file(fsp1,NORMAL_CLOSE);
01758 
01759         /* Ensure the modtime is set correctly on the destination file. */
01760         fsp_set_pending_modtime(fsp2, get_mtimespec(&sbuf1));
01761 
01762         status = close_file(fsp2,NORMAL_CLOSE);
01763 
01764         /* Grrr. We have to do this as open_file_ntcreate adds aARCH when it
01765            creates the file. This isn't the correct thing to do in the copy
01766            case. JRA */
01767         file_set_dosmode(conn, newname, fattr, &sbuf2,
01768                          parent_dirname(newname));
01769 
01770         if (ret < (SMB_OFF_T)sbuf1.st_size) {
01771                 return NT_STATUS_DISK_FULL;
01772         }
01773 
01774         if (!NT_STATUS_IS_OK(status)) {
01775                 DEBUG(3,("copy_internals: Error %s copy file %s to %s\n",
01776                         nt_errstr(status), oldname, newname));
01777         }
01778         return status;
01779 }

int reply_ntrename ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize 
)

nttrans.c1785 行で定義されています。

参照先 copy_internals()hardlink_internals()is_ntfs_stream_name()ms_has_wild()open_was_deferred()rename_internals()resolve_dfspath()set_message()srvstr_get_path_wcard()status.

01787 {
01788         int outsize = 0;
01789         pstring oldname;
01790         pstring newname;
01791         char *p;
01792         NTSTATUS status;
01793         BOOL src_has_wcard = False;
01794         BOOL dest_has_wcard = False;
01795         uint32 attrs = SVAL(inbuf,smb_vwv0);
01796         uint16 rename_type = SVAL(inbuf,smb_vwv1);
01797 
01798         START_PROFILE(SMBntrename);
01799 
01800         p = smb_buf(inbuf) + 1;
01801         p += srvstr_get_path_wcard(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status, &src_has_wcard);
01802         if (!NT_STATUS_IS_OK(status)) {
01803                 END_PROFILE(SMBntrename);
01804                 return ERROR_NT(status);
01805         }
01806 
01807         if( is_ntfs_stream_name(oldname)) {
01808                 /* Can't rename a stream. */
01809                 END_PROFILE(SMBntrename);
01810                 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
01811         }
01812 
01813         if (ms_has_wild(oldname)) {
01814                 END_PROFILE(SMBntrename);
01815                 return ERROR_NT(NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
01816         }
01817 
01818         p++;
01819         p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &dest_has_wcard);
01820         if (!NT_STATUS_IS_OK(status)) {
01821                 END_PROFILE(SMBntrename);
01822                 return ERROR_NT(status);
01823         }
01824         
01825         status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, oldname);
01826         if (!NT_STATUS_IS_OK(status)) {
01827                 END_PROFILE(SMBntrename);
01828                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
01829                         return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
01830                 }
01831                 return ERROR_NT(status);
01832         }
01833 
01834         status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname);
01835         if (!NT_STATUS_IS_OK(status)) {
01836                 END_PROFILE(SMBntrename);
01837                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
01838                         return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
01839                 }
01840                 return ERROR_NT(status);
01841         }
01842 
01843         DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
01844         
01845         switch(rename_type) {
01846                 case RENAME_FLAG_RENAME:
01847                         status = rename_internals(conn, oldname, newname, attrs, False, src_has_wcard, dest_has_wcard);
01848                         break;
01849                 case RENAME_FLAG_HARD_LINK:
01850                         if (src_has_wcard || dest_has_wcard) {
01851                                 /* No wildcards. */
01852                                 status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
01853                         } else {
01854                                 status = hardlink_internals(conn, oldname, newname);
01855                         }
01856                         break;
01857                 case RENAME_FLAG_COPY:
01858                         if (src_has_wcard || dest_has_wcard) {
01859                                 /* No wildcards. */
01860                                 status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
01861                         } else {
01862                                 status = copy_internals(conn, oldname, newname, attrs);
01863                         }
01864                         break;
01865                 case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
01866                         status = NT_STATUS_INVALID_PARAMETER;
01867                         break;
01868                 default:
01869                         status = NT_STATUS_ACCESS_DENIED; /* Default error. */
01870                         break;
01871         }
01872 
01873         if (!NT_STATUS_IS_OK(status)) {
01874                 END_PROFILE(SMBntrename);
01875                 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
01876                         /* We have re-scheduled this call. */
01877                         return -1;
01878                 }
01879                 return ERROR_NT(status);
01880         }
01881 
01882         outsize = set_message(outbuf,0,0,False);
01883   
01884         END_PROFILE(SMBntrename);
01885         return(outsize);
01886 }

static int call_nt_transact_notify_change ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize,
uint16 **  ppsetup,
uint32  setup_count,
char **  ppparams,
uint32  parameter_count,
char **  ppdata,
uint32  data_count,
uint32  max_data_count,
uint32  max_param_count 
) [static]

nttrans.c1893 行で定義されています。

参照先 change_notify_add_request()change_notify_create()change_notify_reply()files_struct::connfile_fsp()files_struct::fsp_namefiles_struct::is_directoryfiles_struct::notifynotify_filter_string()nt_errstr()notify_change_buf::num_changesstatus.

参照元 handle_nttrans().

01902 {
01903         uint16 *setup = *ppsetup;
01904         files_struct *fsp;
01905         uint32 filter;
01906         NTSTATUS status;
01907         BOOL recursive;
01908 
01909         if(setup_count < 6) {
01910                 return ERROR_DOS(ERRDOS,ERRbadfunc);
01911         }
01912 
01913         fsp = file_fsp((char *)setup,4);
01914         filter = IVAL(setup, 0);
01915         recursive = (SVAL(setup, 6) != 0) ? True : False;
01916 
01917         DEBUG(3,("call_nt_transact_notify_change\n"));
01918 
01919         if(!fsp) {
01920                 return ERROR_DOS(ERRDOS,ERRbadfid);
01921         }
01922 
01923         {
01924                 char *filter_string;
01925 
01926                 if (!(filter_string = notify_filter_string(NULL, filter))) {
01927                         return ERROR_NT(NT_STATUS_NO_MEMORY);
01928                 }
01929 
01930                 DEBUG(3,("call_nt_transact_notify_change: notify change "
01931                          "called on %s, filter = %s, recursive = %d\n",
01932                          fsp->fsp_name, filter_string, recursive));
01933 
01934                 TALLOC_FREE(filter_string);
01935         }
01936 
01937         if((!fsp->is_directory) || (conn != fsp->conn)) {
01938                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
01939         }
01940 
01941         if (fsp->notify == NULL) {
01942 
01943                 status = change_notify_create(fsp, filter, recursive);
01944 
01945                 if (!NT_STATUS_IS_OK(status)) {
01946                         DEBUG(10, ("change_notify_create returned %s\n",
01947                                    nt_errstr(status)));
01948                         return ERROR_NT(status);
01949                 }
01950         }
01951 
01952         if (fsp->notify->num_changes != 0) {
01953 
01954                 /*
01955                  * We've got changes pending, respond immediately
01956                  */
01957 
01958                 /*
01959                  * TODO: write a torture test to check the filtering behaviour
01960                  * here.
01961                  */
01962 
01963                 change_notify_reply(inbuf, max_param_count, fsp->notify);
01964 
01965                 /*
01966                  * change_notify_reply() above has independently sent its
01967                  * results
01968                  */
01969                 return -1;
01970         }
01971 
01972         /*
01973          * No changes pending, queue the request
01974          */
01975 
01976         status = change_notify_add_request(inbuf, max_param_count, filter,
01977                         recursive, fsp);
01978         if (!NT_STATUS_IS_OK(status)) {
01979                 return ERROR_NT(status);
01980         }
01981 
01982         return -1;
01983 }

static int call_nt_transact_rename ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize,
uint16 **  ppsetup,
uint32  setup_count,
char **  ppparams,
uint32  parameter_count,
char **  ppdata,
uint32  data_count,
uint32  max_data_count 
) [static]

nttrans.c1989 行で定義されています。

参照先 file_fsp()open_was_deferred()rename_internals()send_nt_replies()srvstr_get_path_wcard()status.

参照元 handle_nttrans().

01993 {
01994         char *params = *ppparams;
01995         pstring new_name;
01996         files_struct *fsp = NULL;
01997         BOOL replace_if_exists = False;
01998         BOOL dest_has_wcard = False;
01999         NTSTATUS status;
02000 
02001         if(parameter_count < 5) {
02002                 return ERROR_DOS(ERRDOS,ERRbadfunc);
02003         }
02004 
02005         fsp = file_fsp(params, 0);
02006         replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
02007         CHECK_FSP(fsp, conn);
02008         srvstr_get_path_wcard(inbuf, new_name, params+4, sizeof(new_name), parameter_count - 4,
02009                         STR_TERMINATE, &status, &dest_has_wcard);
02010         if (!NT_STATUS_IS_OK(status)) {
02011                 return ERROR_NT(status);
02012         }
02013 
02014         status = rename_internals(conn, fsp->fsp_name,
02015                                   new_name, 0, replace_if_exists, False, dest_has_wcard);
02016 
02017         if (!NT_STATUS_IS_OK(status)) {
02018                 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
02019                         /* We have re-scheduled this call. */
02020                         return -1;
02021                 }
02022                 return ERROR_NT(status);
02023         }
02024 
02025         /*
02026          * Rename was successful.
02027          */
02028         send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
02029         
02030         DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", 
02031                  fsp->fsp_name, new_name));
02032         
02033         return -1;
02034 }

static size_t get_null_nt_acl ( TALLOC_CTX mem_ctx,
SEC_DESC **  ppsd 
) [static]

nttrans.c2040 行で定義されています。

参照先 global_sid_Worldmake_standard_sec_desc().

参照元 call_nt_transact_query_security_desc().

02041 {
02042         size_t sd_size;
02043 
02044         *ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size);
02045         if(!*ppsd) {
02046                 DEBUG(0,("get_null_nt_acl: Unable to malloc space for security descriptor.\n"));
02047                 sd_size = 0;
02048         }
02049 
02050         return sd_size;
02051 }

static int call_nt_transact_query_security_desc ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize,
uint16 **  ppsetup,
uint32  setup_count,
char **  ppparams,
uint32  parameter_count,
char **  ppdata,
uint32  data_count,
uint32  max_data_count 
) [static]

nttrans.c2057 行で定義されています。

参照先 fd_handle::fdfiles_struct::fhfile_fsp()files_struct::fsp_nameget_null_nt_acl()nttrans_realloc()prs_init()sec_io_desc()send_nt_replies()talloc_init().

参照元 handle_nttrans().

02061 {
02062         char *params = *ppparams;
02063         char *data = *ppdata;
02064         prs_struct pd;
02065         SEC_DESC *psd = NULL;
02066         size_t sd_size;
02067         uint32 security_info_wanted;
02068         TALLOC_CTX *mem_ctx;
02069         files_struct *fsp = NULL;
02070 
02071         if(parameter_count < 8) {
02072                 return ERROR_DOS(ERRDOS,ERRbadfunc);
02073         }
02074 
02075         fsp = file_fsp(params,0);
02076         if(!fsp) {
02077                 return ERROR_DOS(ERRDOS,ERRbadfid);
02078         }
02079 
02080         security_info_wanted = IVAL(params,4);
02081 
02082         DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name,
02083                         (unsigned int)security_info_wanted ));
02084 
02085         params = nttrans_realloc(ppparams, 4);
02086         if(params == NULL) {
02087                 return ERROR_DOS(ERRDOS,ERRnomem);
02088         }
02089 
02090         if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) {
02091                 DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
02092                 return ERROR_DOS(ERRDOS,ERRnomem);
02093         }
02094 
02095         /*
02096          * Get the permissions to return.
02097          */
02098 
02099         if (!lp_nt_acl_support(SNUM(conn))) {
02100                 sd_size = get_null_nt_acl(mem_ctx, &psd);
02101         } else {
02102                 sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, security_info_wanted, &psd);
02103         }
02104 
02105         if (sd_size == 0) {
02106                 talloc_destroy(mem_ctx);
02107                 return(UNIXERROR(ERRDOS,ERRnoaccess));
02108         }
02109 
02110         DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));
02111 
02112         SIVAL(params,0,(uint32)sd_size);
02113 
02114         if(max_data_count < sd_size) {
02115 
02116                 send_nt_replies(outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
02117                                 params, 4, *ppdata, 0);
02118                 talloc_destroy(mem_ctx);
02119                 return -1;
02120         }
02121 
02122         /*
02123          * Allocate the data we will point this at.
02124          */
02125 
02126         data = nttrans_realloc(ppdata, sd_size);
02127         if(data == NULL) {
02128                 talloc_destroy(mem_ctx);
02129                 return ERROR_DOS(ERRDOS,ERRnomem);
02130         }
02131 
02132         /*
02133          * Init the parse struct we will marshall into.
02134          */
02135 
02136         prs_init(&pd, 0, mem_ctx, MARSHALL);
02137 
02138         /*
02139          * Setup the prs_struct to point at the memory we just
02140          * allocated.
02141          */
02142 
02143         prs_give_memory( &pd, data, (uint32)sd_size, False);
02144 
02145         /*
02146          * Finally, linearize into the outgoing buffer.
02147          */
02148 
02149         if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
02150                 DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
02151 security descriptor.\n"));
02152                 /*
02153                  * Return access denied for want of a better error message..
02154                  */ 
02155                 talloc_destroy(mem_ctx);
02156                 return(UNIXERROR(ERRDOS,ERRnoaccess));
02157         }
02158 
02159         /*
02160          * Now we can delete the security descriptor.
02161          */
02162 
02163         talloc_destroy(mem_ctx);
02164 
02165         send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, 4, data,
02166                         (int)sd_size);
02167         return -1;
02168 }

static int call_nt_transact_set_security_desc ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize,
uint16 **  ppsetup,
uint32  setup_count,
char **  ppparams,
uint32  parameter_count,
char **  ppdata,
uint32  data_count,
uint32  max_data_count 
) [static]

nttrans.c2174 行で定義されています。

参照先 file_fsp()files_struct::fsp_namesend_nt_replies()set_sd().

参照元 handle_nttrans().

02178 {
02179         char *params= *ppparams;
02180         char *data = *ppdata;
02181         files_struct *fsp = NULL;
02182         uint32 security_info_sent = 0;
02183         NTSTATUS nt_status;
02184 
02185         if(parameter_count < 8) {
02186                 return ERROR_DOS(ERRDOS,ERRbadfunc);
02187         }
02188 
02189         if((fsp = file_fsp(params,0)) == NULL) {
02190                 return ERROR_DOS(ERRDOS,ERRbadfid);
02191         }
02192 
02193         if(!lp_nt_acl_support(SNUM(conn))) {
02194                 goto done;
02195         }
02196 
02197         security_info_sent = IVAL(params,4);
02198 
02199         DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
02200                 (unsigned int)security_info_sent ));
02201 
02202         if (data_count == 0) {
02203                 return ERROR_DOS(ERRDOS, ERRnoaccess);
02204         }
02205 
02206         if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent))) {
02207                 return ERROR_NT(nt_status);
02208         }
02209 
02210   done:
02211 
02212         send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
02213         return -1;
02214 }

static int call_nt_transact_ioctl ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize,
uint16 **  ppsetup,
uint32  setup_count,
char **  ppparams,
uint32  parameter_count,
char **  ppdata,
uint32  data_count,
uint32  max_data_count 
) [static]

nttrans.c2220 行で定義されています。

参照先 connection_struct::connectpatherrnofile_fsp()files_struct::fsp_nameshadow_copy_data::labelsshadow_copy_data::mem_ctxnttrans_realloc()shadow_copy_data::num_volumessend_nt_replies()sid_parse()sid_string_static()sid_to_uid()talloc_init().

参照元 handle_nttrans().

02224 {
02225         uint32 function;
02226         uint16 fidnum;
02227         files_struct *fsp;
02228         uint8 isFSctl;
02229         uint8 compfilter;
02230         static BOOL logged_message;
02231         char *pdata = *ppdata;
02232 
02233         if (setup_count != 8) {
02234                 DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
02235                 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
02236         }
02237 
02238         function = IVAL(*ppsetup, 0);
02239         fidnum = SVAL(*ppsetup, 4);
02240         isFSctl = CVAL(*ppsetup, 6);
02241         compfilter = CVAL(*ppsetup, 7);
02242 
02243         DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", 
02244                  function, fidnum, isFSctl, compfilter));
02245 
02246         fsp=file_fsp((char *)*ppsetup, 4);
02247         /* this check is done in each implemented function case for now
02248            because I don't want to break anything... --metze
02249         FSP_BELONGS_CONN(fsp,conn);*/
02250 
02251         switch (function) {
02252         case FSCTL_SET_SPARSE:
02253                 /* pretend this succeeded - tho strictly we should
02254                    mark the file sparse (if the local fs supports it)
02255                    so we can know if we need to pre-allocate or not */
02256 
02257                 DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
02258                 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL,
02259                                 0);
02260                 return -1;
02261         
02262         case FSCTL_0x000900C0:
02263                 /* pretend this succeeded - don't know what this really is
02264                    but works ok like this --metze
02265                  */
02266 
02267                 DEBUG(10,("FSCTL_0x000900C0: called on FID[0x%04X](but not implemented)\n",fidnum));
02268                 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL,
02269                                 0);
02270                 return -1;
02271 
02272         case FSCTL_GET_REPARSE_POINT:
02273                 /* pretend this fail - my winXP does it like this
02274                  * --metze
02275                  */
02276 
02277                 DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
02278                 send_nt_replies(outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT,
02279                                 NULL, 0, NULL, 0);
02280                 return -1;
02281 
02282         case FSCTL_SET_REPARSE_POINT:
02283                 /* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case.
02284                  * --metze
02285                  */
02286 
02287                 DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
02288                 send_nt_replies(outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT,
02289                                 NULL, 0, NULL, 0);
02290                 return -1;
02291                         
02292         case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/
02293         {
02294                 /*
02295                  * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
02296                  * and return their volume names.  If max_data_count is 16, then it is just
02297                  * asking for the number of volumes and length of the combined names.
02298                  *
02299                  * pdata is the data allocated by our caller, but that uses
02300                  * total_data_count (which is 0 in our case) rather than max_data_count.
02301                  * Allocate the correct amount and return the pointer to let
02302                  * it be deallocated when we return.
02303                  */
02304                 SHADOW_COPY_DATA *shadow_data = NULL;
02305                 TALLOC_CTX *shadow_mem_ctx = NULL;
02306                 BOOL labels = False;
02307                 uint32 labels_data_count = 0;
02308                 uint32 i;
02309                 char *cur_pdata;
02310 
02311                 FSP_BELONGS_CONN(fsp,conn);
02312 
02313                 if (max_data_count < 16) {
02314                         DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
02315                                 max_data_count));
02316                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
02317                 }
02318 
02319                 if (max_data_count > 16) {
02320                         labels = True;
02321                 }
02322 
02323                 shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA");
02324                 if (shadow_mem_ctx == NULL) {
02325                         DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n"));
02326                         return ERROR_NT(NT_STATUS_NO_MEMORY);
02327                 }
02328 
02329                 shadow_data = TALLOC_ZERO_P(shadow_mem_ctx,SHADOW_COPY_DATA);
02330                 if (shadow_data == NULL) {
02331                         DEBUG(0,("TALLOC_ZERO() failed!\n"));
02332                         talloc_destroy(shadow_mem_ctx);
02333                         return ERROR_NT(NT_STATUS_NO_MEMORY);
02334                 }
02335                 
02336                 shadow_data->mem_ctx = shadow_mem_ctx;
02337                 
02338                 /*
02339                  * Call the VFS routine to actually do the work.
02340                  */
02341                 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
02342                         talloc_destroy(shadow_data->mem_ctx);
02343                         if (errno == ENOSYS) {
02344                                 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n", 
02345                                         conn->connectpath));
02346                                 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
02347                         } else {
02348                                 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n", 
02349                                         conn->connectpath));
02350                                 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);                        
02351                         }
02352                 }
02353 
02354                 labels_data_count = (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))+2;
02355 
02356                 if (!labels) {
02357                         data_count = 16;
02358                 } else {
02359                         data_count = 12+labels_data_count+4;
02360                 }
02361 
02362                 if (max_data_count<data_count) {
02363                         DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
02364                                 max_data_count,data_count));
02365                         talloc_destroy(shadow_data->mem_ctx);
02366                         return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
02367                 }
02368 
02369                 pdata = nttrans_realloc(ppdata, data_count);
02370                 if (pdata == NULL) {
02371                         talloc_destroy(shadow_data->mem_ctx);
02372                         return ERROR_NT(NT_STATUS_NO_MEMORY);
02373                 }               
02374 
02375                 cur_pdata = pdata;
02376 
02377                 /* num_volumes 4 bytes */
02378                 SIVAL(pdata,0,shadow_data->num_volumes);
02379 
02380                 if (labels) {
02381                         /* num_labels 4 bytes */
02382                         SIVAL(pdata,4,shadow_data->num_volumes);
02383                 }
02384 
02385                 /* needed_data_count 4 bytes */
02386                 SIVAL(pdata,8,labels_data_count);
02387 
02388                 cur_pdata+=12;
02389 
02390                 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
02391                         shadow_data->num_volumes,fsp->fsp_name));
02392                 if (labels && shadow_data->labels) {
02393                         for (i=0;i<shadow_data->num_volumes;i++) {
02394                                 srvstr_push(outbuf, cur_pdata, shadow_data->labels[i], 2*sizeof(SHADOW_COPY_LABEL), STR_UNICODE|STR_TERMINATE);
02395                                 cur_pdata+=2*sizeof(SHADOW_COPY_LABEL);
02396                                 DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
02397                         }
02398                 }
02399 
02400                 talloc_destroy(shadow_data->mem_ctx);
02401 
02402                 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0,
02403                                 pdata, data_count);
02404 
02405                 return -1;
02406         }
02407         
02408         case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */
02409         {
02410                 /* pretend this succeeded - 
02411                  * 
02412                  * we have to send back a list with all files owned by this SID
02413                  *
02414                  * but I have to check that --metze
02415                  */
02416                 DOM_SID sid;
02417                 uid_t uid;
02418                 size_t sid_len = MIN(data_count-4,SID_MAX_SIZE);
02419                 
02420                 DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum));
02421 
02422                 FSP_BELONGS_CONN(fsp,conn);
02423 
02424                 /* unknown 4 bytes: this is not the length of the sid :-(  */
02425                 /*unknown = IVAL(pdata,0);*/
02426                 
02427                 sid_parse(pdata+4,sid_len,&sid);
02428                 DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));
02429 
02430                 if (!sid_to_uid(&sid, &uid)) {
02431                         DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
02432                                 sid_string_static(&sid),(unsigned long)sid_len));
02433                         uid = (-1);
02434                 }
02435                 
02436                 /* we can take a look at the find source :-)
02437                  *
02438                  * find ./ -uid $uid  -name '*'   is what we need here
02439                  *
02440                  *
02441                  * and send 4bytes len and then NULL terminated unicode strings
02442                  * for each file
02443                  *
02444                  * but I don't know how to deal with the paged results
02445                  * (maybe we can hang the result anywhere in the fsp struct)
02446                  *
02447                  * we don't send all files at once
02448                  * and at the next we should *not* start from the beginning, 
02449                  * so we have to cache the result 
02450                  *
02451                  * --metze
02452                  */
02453                 
02454                 /* this works for now... */
02455                 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0,
02456                                 NULL, 0);
02457                 return -1;      
02458         }       
02459         default:
02460                 if (!logged_message) {
02461                         logged_message = True; /* Only print this once... */
02462                         DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
02463                                  function));
02464                 }
02465         }
02466 
02467         return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
02468 }

static int call_nt_transact_get_user_quota ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize,
uint16 **  ppsetup,
uint32  setup_count,
char **  ppparams,
uint32  parameter_count,
char **  ppdata,
uint32  data_count,
uint32  max_data_count 
) [static]

nttrans.c2476 行で定義されています。

参照先 current_userfiles_struct::fake_file_handlefile_fsp()files_struct::fnumfree_ntquota_list()_SMB_NTQUOTA_STRUCT::hardlimlevel_SMB_NTQUOTA_LIST::nextnttrans_realloc()_FAKE_FILE_HANDLE::pd_SMB_NTQUOTA_HANDLE::quota_list_SMB_NTQUOTA_LIST::quotassend_nt_replies()_SMB_NTQUOTA_STRUCT::sidsid_linearize()sid_parse()sid_size()SMB_USER_QUOTA_TYPE_SMB_NTQUOTA_STRUCT::softlim_SMB_NTQUOTA_HANDLE::tmp_list_unix_token::uid_SMB_NTQUOTA_STRUCT::usedspaceconnection_struct::usercurrent_user::utvfs_get_ntquota()vfs_get_user_ntquota_list().

参照元 handle_nttrans().

02480 {
02481         NTSTATUS nt_status = NT_STATUS_OK;
02482         char *params = *ppparams;
02483         char *pdata = *ppdata;
02484         char *entry;
02485         int data_len=0,param_len=0;
02486         int qt_len=0;
02487         int entry_len = 0;
02488         files_struct *fsp = NULL;
02489         uint16 level = 0;
02490         size_t sid_len;
02491         DOM_SID sid;
02492         BOOL start_enum = True;
02493         SMB_NTQUOTA_STRUCT qt;
02494         SMB_NTQUOTA_LIST *tmp_list;
02495         SMB_NTQUOTA_HANDLE *qt_handle = NULL;
02496 
02497         ZERO_STRUCT(qt);
02498 
02499         /* access check */
02500         if (current_user.ut.uid != 0) {
02501                 DEBUG(1,("get_user_quota: access_denied service [%s] user [%s]\n",
02502                         lp_servicename(SNUM(conn)),conn->user));
02503                 return ERROR_DOS(ERRDOS,ERRnoaccess);
02504         }
02505 
02506         /*
02507          * Ensure minimum number of parameters sent.
02508          */
02509 
02510         if (parameter_count < 4) {
02511                 DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count));
02512                 return ERROR_DOS(ERRDOS,ERRinvalidparam);
02513         }
02514         
02515         /* maybe we can check the quota_fnum */
02516         fsp = file_fsp(params,0);
02517         if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
02518                 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
02519                 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
02520         }
02521 
02522         /* the NULL pointer checking for fsp->fake_file_handle->pd
02523          * is done by CHECK_NTQUOTA_HANDLE_OK()
02524          */
02525         qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd;
02526 
02527         level = SVAL(params,2);
02528         
02529         /* unknown 12 bytes leading in params */ 
02530         
02531         switch (level) {
02532                 case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE:
02533                         /* seems that we should continue with the enum here --metze */
02534 
02535                         if (qt_handle->quota_list!=NULL && 
02536                             qt_handle->tmp_list==NULL) {
02537                 
02538                                 /* free the list */
02539                                 free_ntquota_list(&(qt_handle->quota_list));
02540 
02541                                 /* Realloc the size of parameters and data we will return */
02542                                 param_len = 4;
02543                                 params = nttrans_realloc(ppparams, param_len);
02544                                 if(params == NULL) {
02545                                         return ERROR_DOS(ERRDOS,ERRnomem);
02546                                 }
02547 
02548                                 data_len = 0;
02549                                 SIVAL(params,0,data_len);
02550 
02551                                 break;
02552                         }
02553 
02554                         start_enum = False;
02555 
02556                 case TRANSACT_GET_USER_QUOTA_LIST_START:
02557 
02558                         if (qt_handle->quota_list==NULL &&
02559                                 qt_handle->tmp_list==NULL) {
02560                                 start_enum = True;
02561                         }
02562 
02563                         if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0)
02564                                 return ERROR_DOS(ERRSRV,ERRerror);
02565 
02566                         /* Realloc the size of parameters and data we will return */
02567                         param_len = 4;
02568                         params = nttrans_realloc(ppparams, param_len);
02569                         if(params == NULL) {
02570                                 return ERROR_DOS(ERRDOS,ERRnomem);
02571                         }
02572 
02573                         /* we should not trust the value in max_data_count*/
02574                         max_data_count = MIN(max_data_count,2048);
02575                         
02576                         pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/
02577                         if(pdata == NULL) {
02578                                 return ERROR_DOS(ERRDOS,ERRnomem);
02579                         }
02580 
02581                         entry = pdata;
02582 
02583                         /* set params Size of returned Quota Data 4 bytes*/
02584                         /* but set it later when we know it */
02585                 
02586                         /* for each entry push the data */
02587 
02588                         if (start_enum) {
02589                                 qt_handle->tmp_list = qt_handle->quota_list;
02590                         }
02591 
02592                         tmp_list = qt_handle->tmp_list;
02593 
02594                         for (;((tmp_list!=NULL)&&((qt_len +40+SID_MAX_SIZE)<max_data_count));
02595                                 tmp_list=tmp_list->next,entry+=entry_len,qt_len+=entry_len) {
02596 
02597                                 sid_len = sid_size(&tmp_list->quotas->sid);
02598                                 entry_len = 40 + sid_len;
02599 
02600                                 /* nextoffset entry 4 bytes */
02601                                 SIVAL(entry,0,entry_len);
02602                 
02603                                 /* then the len of the SID 4 bytes */
02604                                 SIVAL(entry,4,sid_len);
02605                                 
02606                                 /* unknown data 8 bytes SMB_BIG_UINT */
02607                                 SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/
02608                                 
02609                                 /* the used disk space 8 bytes SMB_BIG_UINT */
02610                                 SBIG_UINT(entry,16,tmp_list->quotas->usedspace);
02611                                 
02612                                 /* the soft quotas 8 bytes SMB_BIG_UINT */
02613                                 SBIG_UINT(entry,24,tmp_list->quotas->softlim);
02614                                 
02615                                 /* the hard quotas 8 bytes SMB_BIG_UINT */
02616                                 SBIG_UINT(entry,32,tmp_list->quotas->hardlim);
02617                                 
02618                                 /* and now the SID */
02619                                 sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid);
02620                         }
02621                         
02622                         qt_handle->tmp_list = tmp_list;
02623                         
02624                         /* overwrite the offset of the last entry */
02625                         SIVAL(entry-entry_len,0,0);
02626 
02627                         data_len = 4+qt_len;
02628                         /* overwrite the params quota_data_len */
02629                         SIVAL(params,0,data_len);
02630 
02631                         break;
02632 
02633                 case TRANSACT_GET_USER_QUOTA_FOR_SID:
02634                         
02635                         /* unknown 4 bytes IVAL(pdata,0) */     
02636                         
02637                         if (data_count < 8) {
02638                                 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8));
02639                                 return ERROR_DOS(ERRDOS,ERRunknownlevel);                               
02640                         }
02641 
02642                         sid_len = IVAL(pdata,4);
02643                         /* Ensure this is less than 1mb. */
02644                         if (sid_len > (1024*1024)) {
02645                                 return ERROR_DOS(ERRDOS,ERRnomem);
02646                         }
02647 
02648                         if (data_count < 8+sid_len) {
02649                                 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len)));
02650                                 return ERROR_DOS(ERRDOS,ERRunknownlevel);                               
02651                         }
02652 
02653                         data_len = 4+40+sid_len;
02654 
02655                         if (max_data_count < data_len) {
02656                                 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: max_data_count(%d) < data_len(%d)\n",
02657                                         max_data_count, data_len));
02658                                 param_len = 4;
02659                                 SIVAL(params,0,data_len);
02660                                 data_len = 0;
02661                                 nt_status = NT_STATUS_BUFFER_TOO_SMALL;
02662                                 break;
02663                         }
02664 
02665                         sid_parse(pdata+8,sid_len,&sid);
02666                 
02667                         if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
02668                                 ZERO_STRUCT(qt);
02669                                 /* 
02670                                  * we have to return zero's in all fields 
02671                                  * instead of returning an error here
02672                                  * --metze
02673                                  */
02674                         }
02675 
02676                         /* Realloc the size of parameters and data we will return */
02677                         param_len = 4;
02678                         params = nttrans_realloc(ppparams, param_len);
02679                         if(params == NULL) {
02680                                 return ERROR_DOS(ERRDOS,ERRnomem);
02681                         }
02682 
02683                         pdata = nttrans_realloc(ppdata, data_len);
02684                         if(pdata == NULL) {
02685                                 return ERROR_DOS(ERRDOS,ERRnomem);
02686                         }
02687 
02688                         entry = pdata;
02689 
02690                         /* set params Size of returned Quota Data 4 bytes*/
02691                         SIVAL(params,0,data_len);
02692         
02693                         /* nextoffset entry 4 bytes */
02694                         SIVAL(entry,0,0);
02695         
02696                         /* then the len of the SID 4 bytes */
02697                         SIVAL(entry,4,sid_len);
02698                         
02699                         /* unknown data 8 bytes SMB_BIG_UINT */
02700                         SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/
02701                         
02702                         /* the used disk space 8 bytes SMB_BIG_UINT */
02703                         SBIG_UINT(entry,16,qt.usedspace);
02704                         
02705                         /* the soft quotas 8 bytes SMB_BIG_UINT */
02706                         SBIG_UINT(entry,24,qt.softlim);
02707                         
02708                         /* the hard quotas 8 bytes SMB_BIG_UINT */
02709                         SBIG_UINT(entry,32,qt.hardlim);
02710                         
02711                         /* and now the SID */
02712                         sid_linearize(entry+40, sid_len, &sid);
02713 
02714                         break;
02715 
02716                 default:
02717                         DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level));
02718                         return ERROR_DOS(ERRSRV,ERRerror);
02719                         break;
02720         }
02721 
02722         send_nt_replies(outbuf, bufsize, nt_status, params, param_len,
02723                         pdata, data_len);
02724 
02725         return -1;
02726 }

static int call_nt_transact_set_user_quota ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize,
uint16 **  ppsetup,
uint32  setup_count,
char **  ppparams,
uint32  parameter_count,
char **  ppdata,
uint32  data_count,
uint32  max_data_count 
) [static]

nttrans.c2732 行で定義されています。

参照先 current_userfile_fsp()_SMB_NTQUOTA_STRUCT::hardlimsend_nt_replies()sid_parse()sid_string_static()SMB_USER_QUOTA_TYPE_SMB_NTQUOTA_STRUCT::softlim_unix_token::uid_SMB_NTQUOTA_STRUCT::usedspaceconnection_struct::usercurrent_user::utvfs_set_ntquota().

参照元 handle_nttrans().

02736 {
02737         char *params = *ppparams;
02738         char *pdata = *ppdata;
02739         int data_len=0,param_len=0;
02740         SMB_NTQUOTA_STRUCT qt;
02741         size_t sid_len;
02742         DOM_SID sid;
02743         files_struct *fsp = NULL;
02744 
02745         ZERO_STRUCT(qt);
02746 
02747         /* access check */
02748         if (current_user.ut.uid != 0) {
02749                 DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n",
02750                         lp_servicename(SNUM(conn)),conn->user));
02751                 return ERROR_DOS(ERRDOS,ERRnoaccess);
02752         }
02753 
02754         /*
02755          * Ensure minimum number of parameters sent.
02756          */
02757 
02758         if (parameter_count < 2) {
02759                 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
02760                 return ERROR_DOS(ERRDOS,ERRinvalidparam);
02761         }
02762         
02763         /* maybe we can check the quota_fnum */
02764         fsp = file_fsp(params,0);
02765         if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
02766                 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
02767                 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
02768         }
02769 
02770         if (data_count < 40) {
02771                 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40));
02772                 return ERROR_DOS(ERRDOS,ERRunknownlevel);               
02773         }
02774 
02775         /* offset to next quota record.
02776          * 4 bytes IVAL(pdata,0)
02777          * unused here...
02778          */
02779 
02780         /* sid len */
02781         sid_len = IVAL(pdata,4);
02782 
02783         if (data_count < 40+sid_len) {
02784                 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len));
02785                 return ERROR_DOS(ERRDOS,ERRunknownlevel);               
02786         }
02787 
02788         /* unknown 8 bytes in pdata 
02789          * maybe its the change time in NTTIME
02790          */
02791 
02792         /* the used space 8 bytes (SMB_BIG_UINT)*/
02793         qt.usedspace = (SMB_BIG_UINT)IVAL(pdata,16);
02794 #ifdef LARGE_SMB_OFF_T
02795         qt.usedspace |= (((SMB_BIG_UINT)IVAL(pdata,20)) << 32);
02796 #else /* LARGE_SMB_OFF_T */
02797         if ((IVAL(pdata,20) != 0)&&
02798                 ((qt.usedspace != 0xFFFFFFFF)||
02799                 (IVAL(pdata,20)!=0xFFFFFFFF))) {
02800                 /* more than 32 bits? */
02801                 return ERROR_DOS(ERRDOS,ERRunknownlevel);
02802         }
02803 #endif /* LARGE_SMB_OFF_T */
02804 
02805         /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
02806         qt.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
02807 #ifdef LARGE_SMB_OFF_T
02808         qt.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
02809 #else /* LARGE_SMB_OFF_T */
02810         if ((IVAL(pdata,28) != 0)&&
02811                 ((qt.softlim != 0xFFFFFFFF)||
02812                 (IVAL(pdata,28)!=0xFFFFFFFF))) {
02813                 /* more than 32 bits? */
02814                 return ERROR_DOS(ERRDOS,ERRunknownlevel);
02815         }
02816 #endif /* LARGE_SMB_OFF_T */
02817 
02818         /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
02819         qt.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
02820 #ifdef LARGE_SMB_OFF_T
02821         qt.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
02822 #else /* LARGE_SMB_OFF_T */
02823         if ((IVAL(pdata,36) != 0)&&
02824                 ((qt.hardlim != 0xFFFFFFFF)||
02825                 (IVAL(pdata,36)!=0xFFFFFFFF))) {
02826                 /* more than 32 bits? */
02827                 return ERROR_DOS(ERRDOS,ERRunknownlevel);
02828         }
02829 #endif /* LARGE_SMB_OFF_T */
02830         
02831         sid_parse(pdata+40,sid_len,&sid);
02832         DEBUGADD(8,("SID: %s\n",sid_string_static(&sid)));
02833 
02834         /* 44 unknown bytes left... */
02835 
02836         if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
02837                 return ERROR_DOS(ERRSRV,ERRerror);      
02838         }
02839 
02840         send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, param_len,
02841                         pdata, data_len);
02842 
02843         return -1;
02844 }

static int handle_nttrans ( connection_struct conn,
struct trans_state state,
char *  inbuf,
char *  outbuf,
int  size,
int  bufsize 
) [static]

nttrans.c2847 行で定義されています。

参照先 trans_state::callcall_nt_transact_create()call_nt_transact_get_user_quota()call_nt_transact_ioctl()call_nt_transact_notify_change()call_nt_transact_query_security_desc()call_nt_transact_rename()call_nt_transact_set_security_desc()call_nt_transact_set_user_quota()trans_state::datatrans_state::max_data_returntrans_state::max_param_returntrans_state::paramProtocolPROTOCOL_NT1trans_state::setuptrans_state::setup_counttrans_state::total_datatrans_state::total_param.

参照元 reply_nttrans()reply_nttranss().

02850 {
02851         int outsize;
02852 
02853         if (Protocol >= PROTOCOL_NT1) {
02854                 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
02855         }
02856 
02857         /* Now we must call the relevant NT_TRANS function */
02858         switch(state->call) {
02859                 case NT_TRANSACT_CREATE:
02860                 {
02861                         START_PROFILE(NT_transact_create);
02862                         outsize = call_nt_transact_create(conn, inbuf, outbuf,
02863                                                           size, bufsize, 
02864                                                         &state->setup, state->setup_count,
02865                                                         &state->param, state->total_param, 
02866                                                         &state->data, state->total_data,
02867                                                           state->max_data_return);
02868                         END_PROFILE(NT_transact_create);
02869                         break;
02870                 }
02871 
02872                 case NT_TRANSACT_IOCTL:
02873                 {
02874                         START_PROFILE(NT_transact_ioctl);
02875                         outsize = call_nt_transact_ioctl(conn, inbuf, outbuf,
02876                                                          size, bufsize, 
02877                                                          &state->setup, state->setup_count,
02878                                                          &state->param, state->total_param, 
02879                                                          &state->data, state->total_data, state->max_data_return);
02880                         END_PROFILE(NT_transact_ioctl);
02881                         break;
02882                 }
02883 
02884                 case NT_TRANSACT_SET_SECURITY_DESC:
02885                 {
02886                         START_PROFILE(NT_transact_set_security_desc);
02887                         outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf, 
02888                                                          size, bufsize, 
02889                                                          &state->setup, state->setup_count,
02890                                                          &state->param, state->total_param, 
02891                                                          &state->data, state->total_data, state->max_data_return);
02892                         END_PROFILE(NT_transact_set_security_desc);
02893                         break;
02894                 }
02895 
02896                 case NT_TRANSACT_NOTIFY_CHANGE:
02897                 {
02898                         START_PROFILE(NT_transact_notify_change);
02899                         outsize = call_nt_transact_notify_change(
02900                                 conn, inbuf, outbuf, size, bufsize, 
02901                                 &state->setup, state->setup_count,
02902                                 &state->param, state->total_param, 
02903                                 &state->data, state->total_data,
02904                                 state->max_data_return,
02905                                 state->max_param_return);
02906                         END_PROFILE(NT_transact_notify_change);
02907                         break;
02908                 }
02909 
02910                 case NT_TRANSACT_RENAME:
02911                 {
02912                         START_PROFILE(NT_transact_rename);
02913                         outsize = call_nt_transact_rename(conn, inbuf, outbuf,
02914                                                          size, bufsize, 
02915                                                          &state->setup, state->setup_count,
02916                                                          &state->param, state->total_param, 
02917                                                          &state->data, state->total_data, state->max_data_return);
02918                         END_PROFILE(NT_transact_rename);
02919                         break;
02920                 }
02921 
02922                 case NT_TRANSACT_QUERY_SECURITY_DESC:
02923                 {
02924                         START_PROFILE(NT_transact_query_security_desc);
02925                         outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf, 
02926                                                          size, bufsize, 
02927                                                          &state->setup, state->setup_count,
02928                                                          &state->param, state->total_param, 
02929                                                          &state->data, state->total_data, state->max_data_return);
02930                         END_PROFILE(NT_transact_query_security_desc);
02931                         break;
02932                 }
02933 
02934 #ifdef HAVE_SYS_QUOTAS
02935                 case NT_TRANSACT_GET_USER_QUOTA:
02936                 {
02937                         START_PROFILE(NT_transact_get_user_quota);
02938                         outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf, 
02939                                                          size, bufsize, 
02940                                                          &state->setup, state->setup_count,
02941                                                          &state->param, state->total_param, 
02942                                                          &state->data, state->total_data, state->max_data_return);
02943                         END_PROFILE(NT_transact_get_user_quota);
02944                         break;
02945                 }
02946 
02947                 case NT_TRANSACT_SET_USER_QUOTA:
02948                 {
02949                         START_PROFILE(NT_transact_set_user_quota);
02950                         outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf, 
02951                                                          size, bufsize, 
02952                                                          &state->setup, state->setup_count,
02953                                                          &state->param, state->total_param, 
02954                                                          &state->data, state->total_data, state->max_data_return);
02955                         END_PROFILE(NT_transact_set_user_quota);
02956                         break;                                  
02957                 }
02958 #endif /* HAVE_SYS_QUOTAS */
02959 
02960                 default:
02961                         /* Error in request */
02962                         DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n",
02963                                  state->call));
02964                         return ERROR_DOS(ERRSRV,ERRerror);
02965         }
02966         return outsize;
02967 }

int reply_nttrans ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  size,
int  bufsize 
)

nttrans.c2973 行で定義されています。

参照先 allow_new_trans()trans_state::calltrans_state::cmdtrans_state::datadump_data()handle_nttrans()trans_state::max_data_returntrans_state::max_param_returnconnection_struct::mem_ctxtrans_state::midnt_errstr()trans_state::paramconnection_struct::pending_transtrans_state::received_datatrans_state::received_paramresultset_message()trans_state::setuptrans_state::setup_countshow_msg()trans_state::total_datatrans_state::total_paramtrans_state::vuid.

02975 {
02976         int  outsize = 0;
02977         uint32 pscnt = IVAL(inbuf,smb_nt_ParameterCount);
02978         uint32 psoff = IVAL(inbuf,smb_nt_ParameterOffset);
02979         uint32 dscnt = IVAL(inbuf,smb_nt_DataCount);
02980         uint32 dsoff = IVAL(inbuf,smb_nt_DataOffset);
02981         uint32 av_size = size-4;
02982 
02983         uint16 function_code = SVAL( inbuf, smb_nt_Function);
02984         NTSTATUS result;
02985         struct trans_state *state;
02986 
02987         START_PROFILE(SMBnttrans);
02988 
02989         if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
02990                 END_PROFILE(SMBnttrans);
02991                 return ERROR_DOS(ERRSRV,ERRaccess);
02992         }
02993 
02994         result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid));
02995         if (!NT_STATUS_IS_OK(result)) {
02996                 DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result)));
02997                 END_PROFILE(SMBnttrans);
02998                 return ERROR_NT(result);
02999         }
03000 
03001         if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) {
03002                 END_PROFILE(SMBnttrans);
03003                 return ERROR_DOS(ERRSRV,ERRaccess);
03004         }
03005 
03006         state->cmd = SMBnttrans;
03007 
03008         state->mid = SVAL(inbuf,smb_mid);
03009         state->vuid = SVAL(inbuf,smb_uid);
03010         state->total_data = IVAL(inbuf, smb_nt_TotalDataCount);
03011         state->data = NULL;
03012         state->total_param = IVAL(inbuf, smb_nt_TotalParameterCount);
03013         state->param = NULL;
03014         state->max_data_return = IVAL(inbuf,smb_nt_MaxDataCount);       
03015         state->max_param_return = IVAL(inbuf,smb_nt_MaxParameterCount);
03016 
03017         /* setup count is in *words* */
03018         state->setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); 
03019         state->setup = NULL;
03020         state->call = function_code;
03021 
03022         /* 
03023          * All nttrans messages we handle have smb_wct == 19 +
03024          * state->setup_count.  Ensure this is so as a sanity check.
03025          */
03026 
03027         if(CVAL(inbuf, smb_wct) != 19 + (state->setup_count/2)) {
03028                 DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
03029                         CVAL(inbuf, smb_wct), 19 + (state->setup_count/2)));
03030                 goto bad_param;
03031         }
03032 
03033         /* Don't allow more than 128mb for each value. */
03034         if ((state->total_data > (1024*1024*128)) ||
03035             (state->total_param > (1024*1024*128))) {
03036                 END_PROFILE(SMBnttrans);
03037                 return ERROR_DOS(ERRDOS,ERRnomem);
03038         }
03039 
03040         if ((dscnt > state->total_data) || (pscnt > state->total_param))
03041                 goto bad_param;
03042 
03043         if (state->total_data)  {
03044                 /* Can't use talloc here, the core routines do realloc on the
03045                  * params and data. */
03046                 if ((state->data = (char *)SMB_MALLOC(state->total_data)) == NULL) {
03047                         DEBUG(0,("reply_nttrans: data malloc fail for %u "
03048                                  "bytes !\n", (unsigned int)state->total_data));
03049                         TALLOC_FREE(state);
03050                         END_PROFILE(SMBnttrans);
03051                         return(ERROR_DOS(ERRDOS,ERRnomem));
03052                 } 
03053 
03054                 if (dscnt > state->total_data ||
03055                                 dsoff+dscnt < dsoff) {
03056                         goto bad_param;
03057                 }
03058 
03059                 if (dsoff > av_size ||
03060                                 dscnt > av_size ||
03061                                 dsoff+dscnt > av_size) {
03062                         goto bad_param;
03063                 }
03064 
03065                 memcpy(state->data,smb_base(inbuf)+dsoff,dscnt);
03066         }
03067 
03068         if (state->total_param) {
03069                 /* Can't use talloc here, the core routines do realloc on the
03070                  * params and data. */
03071                 if ((state->param = (char *)SMB_MALLOC(state->total_param)) == NULL) {
03072                         DEBUG(0,("reply_nttrans: param malloc fail for %u "
03073                                  "bytes !\n", (unsigned int)state->total_param));
03074                         SAFE_FREE(state->data);
03075                         TALLOC_FREE(state);
03076                         END_PROFILE(SMBnttrans);
03077                         return(ERROR_DOS(ERRDOS,ERRnomem));
03078                 } 
03079 
03080                 if (pscnt > state->total_param ||
03081                                 psoff+pscnt < psoff) {
03082                         goto bad_param;
03083                 }
03084 
03085                 if (psoff > av_size ||
03086                                 pscnt > av_size ||
03087                                 psoff+pscnt > av_size) {
03088                         goto bad_param;
03089                 }
03090 
03091                 memcpy(state->param,smb_base(inbuf)+psoff,pscnt);
03092         }
03093 
03094         state->received_data  = dscnt;
03095         state->received_param = pscnt;
03096 
03097         if(state->setup_count > 0) {
03098                 DEBUG(10,("reply_nttrans: state->setup_count = %d\n",
03099                           state->setup_count));
03100                 state->setup = (uint16 *)TALLOC(state, state->setup_count);
03101                 if (state->setup == NULL) {
03102                         DEBUG(0,("reply_nttrans : Out of memory\n"));
03103                         SAFE_FREE(state->data);
03104                         SAFE_FREE(state->param);
03105                         TALLOC_FREE(state);
03106                         END_PROFILE(SMBnttrans);
03107                         return ERROR_DOS(ERRDOS,ERRnomem);
03108                 }
03109 
03110                 if ((smb_nt_SetupStart + state->setup_count < smb_nt_SetupStart) ||
03111                     (smb_nt_SetupStart + state->setup_count < state->setup_count)) {
03112                         goto bad_param;
03113                 }
03114                 if (smb_nt_SetupStart + state->setup_count > size) {
03115                         goto bad_param;
03116                 }
03117 
03118                 memcpy( state->setup, &inbuf[smb_nt_SetupStart], state->setup_count);
03119                 dump_data(10, (char *)state->setup, state->setup_count);
03120         }
03121 
03122         if ((state->received_data == state->total_data) &&
03123             (state->received_param == state->total_param)) {
03124                 outsize = handle_nttrans(conn, state, inbuf, outbuf,
03125                                          size, bufsize);
03126                 SAFE_FREE(state->param);
03127                 SAFE_FREE(state->data);
03128                 TALLOC_FREE(state);
03129                 END_PROFILE(SMBnttrans);
03130                 return outsize;
03131         }
03132 
03133         DLIST_ADD(conn->pending_trans, state);
03134 
03135         /* We need to send an interim response then receive the rest
03136            of the parameter/data bytes */
03137         outsize = set_message(outbuf,0,0,False);
03138         show_msg(outbuf);
03139         END_PROFILE(SMBnttrans);
03140         return outsize;
03141 
03142   bad_param:
03143 
03144         DEBUG(0,("reply_nttrans: invalid trans parameters\n"));
03145         SAFE_FREE(state->data);
03146         SAFE_FREE(state->param);
03147         TALLOC_FREE(state);
03148         END_PROFILE(SMBnttrans);
03149         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
03150 }

int reply_nttranss ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  size,
int  bufsize 
)

nttrans.c3156 行で定義されています。

参照先 trans_state::cmdtrans_state::datahandle_nttrans()trans_state::midtrans_state::nexttrans_state::paramconnection_struct::pending_transtrans_state::received_datatrans_state::received_paramshow_msg()trans_state::total_datatrans_state::total_param.

03158 {
03159         int outsize = 0;
03160         uint32_t pcnt,poff,dcnt,doff,pdisp,ddisp;
03161         uint32_t av_size = size-4;
03162         struct trans_state *state;
03163 
03164         START_PROFILE(SMBnttranss);
03165 
03166         show_msg(inbuf);
03167 
03168         for (state = conn->pending_trans; state != NULL;
03169              state = state->next) {
03170                 if (state->mid == SVAL(inbuf,smb_mid)) {
03171                         break;
03172                 }
03173         }
03174 
03175         if ((state == NULL) || (state->cmd != SMBnttrans)) {
03176                 END_PROFILE(SMBnttranss);
03177                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
03178         }
03179 
03180         /* Revise state->total_param and state->total_data in case they have
03181            changed downwards */
03182         if (IVAL(inbuf, smb_nts_TotalParameterCount) < state->total_param) {
03183                 state->total_param = IVAL(inbuf, smb_nts_TotalParameterCount);
03184         }
03185         if (IVAL(inbuf, smb_nts_TotalDataCount) < state->total_data) {
03186                 state->total_data = IVAL(inbuf, smb_nts_TotalDataCount);
03187         }
03188 
03189         pcnt = IVAL(inbuf,smb_nts_ParameterCount);
03190         poff = IVAL(inbuf, smb_nts_ParameterOffset);
03191         pdisp = IVAL(inbuf, smb_nts_ParameterDisplacement);
03192 
03193         dcnt = IVAL(inbuf, smb_nts_DataCount);
03194         ddisp = IVAL(inbuf, smb_nts_DataDisplacement);
03195         doff = IVAL(inbuf, smb_nts_DataOffset);
03196 
03197         state->received_param += pcnt;
03198         state->received_data += dcnt;
03199                 
03200         if ((state->received_data > state->total_data) ||
03201             (state->received_param > state->total_param))
03202                 goto bad_param;
03203 
03204         if (pcnt) {
03205                 if (pdisp > state->total_param ||
03206                                 pcnt > state->total_param ||
03207                                 pdisp+pcnt > state->total_param ||
03208                                 pdisp+pcnt < pdisp) {
03209                         goto bad_param;
03210                 }
03211 
03212                 if (poff > av_size ||
03213                                 pcnt > av_size ||
03214                                 poff+pcnt > av_size ||
03215                                 poff+pcnt < poff) {
03216                         goto bad_param;
03217                 }
03218 
03219                 memcpy(state->param+pdisp,smb_base(inbuf)+poff,
03220                        pcnt);
03221         }
03222 
03223         if (dcnt) {
03224                 if (ddisp > state->total_data ||
03225                                 dcnt > state->total_data ||
03226                                 ddisp+dcnt > state->total_data ||
03227                                 ddisp+dcnt < ddisp) {
03228                         goto bad_param;
03229                 }
03230 
03231                 if (doff > av_size ||
03232                                 dcnt > av_size ||
03233                                 doff+dcnt > av_size ||
03234                                 doff+dcnt < doff) {
03235                         goto bad_param;
03236                 }
03237 
03238                 memcpy(state->data+ddisp, smb_base(inbuf)+doff,
03239                        dcnt);      
03240         }
03241 
03242         if ((state->received_param < state->total_param) ||
03243             (state->received_data < state->total_data)) {
03244                 END_PROFILE(SMBnttranss);
03245                 return -1;
03246         }
03247 
03248         /* construct_reply_common has done us the favor to pre-fill the
03249          * command field with SMBnttranss which is wrong :-)
03250          */
03251         SCVAL(outbuf,smb_com,SMBnttrans);
03252 
03253         outsize = handle_nttrans(conn, state, inbuf, outbuf,
03254                                  size, bufsize);
03255 
03256         DLIST_REMOVE(conn->pending_trans, state);
03257         SAFE_FREE(state->data);
03258         SAFE_FREE(state->param);
03259         TALLOC_FREE(state);
03260 
03261         if (outsize == 0) {
03262                 END_PROFILE(SMBnttranss);
03263                 return(ERROR_DOS(ERRSRV,ERRnosupport));
03264         }
03265         
03266         END_PROFILE(SMBnttranss);
03267         return(outsize);
03268 
03269   bad_param:
03270 
03271         DEBUG(0,("reply_nttranss: invalid trans parameters\n"));
03272         DLIST_REMOVE(conn->pending_trans, state);
03273         SAFE_FREE(state->data);
03274         SAFE_FREE(state->param);
03275         TALLOC_FREE(state);
03276         END_PROFILE(SMBnttranss);
03277         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
03278 }


変数

int max_send

process.c38 行で定義されています。

enum protocol_types Protocol

util.c61 行で定義されています。

int smb_read_error

util_sock.c117 行で定義されています。

struct current_user current_user

smbrun.c24 行で定義されています。

const char* known_nt_pipes[] [static]

初期値:

 {
        "\\LANMAN",
        "\\srvsvc",
        "\\samr",
        "\\wkssvc",
        "\\NETLOGON",
        "\\ntlsa",
        "\\ntsvcs",
        "\\lsass",
        "\\lsarpc",
        "\\winreg",
        "\\initshutdown",
        "\\spoolss",
        "\\netdfs",
        "\\rpcecho",
        "\\svcctl",
        "\\eventlog",
        "\\unixinfo",
        NULL
}

nttrans.c29 行で定義されています。

参照元 nt_open_pipe().

BOOL saved_case_sensitive [static]

nttrans.c276 行で定義されています。

参照元 restore_case_semantics()set_posix_case_semantics().

BOOL saved_case_preserve [static]

nttrans.c277 行で定義されています。

参照元 restore_case_semantics()set_posix_case_semantics().

BOOL saved_short_case_preserve [static]

nttrans.c278 行で定義されています。

参照元 restore_case_semantics()set_posix_case_semantics().


Sambaに対してSat Aug 29 21:24:26 2009に生成されました。  doxygen 1.4.7