- pstring fname;
- char *params = *ppparams;
- int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
- /* Breakout the oplock request bits so we can set the
- reply bits separately. */
- int oplock_request = 0;
- mode_t unixmode;
- int fmode=0,rmode=0;
- SMB_OFF_T file_len = 0;
- SMB_STRUCT_STAT sbuf;
- int smb_action = 0;
- BOOL bad_path = False;
- files_struct *fsp = NULL;
- char *p = NULL;
- BOOL stat_open_only = False;
- uint32 flags;
- uint32 desired_access;
- uint32 file_attributes;
- uint32 share_access;
- uint32 create_disposition;
- uint32 create_options;
- uint32 fname_len;
- uint16 root_dir_fid;
- int smb_ofun;
- int smb_open_mode;
- int smb_attr;
-
- DEBUG(5,("call_nt_transact_create\n"));
-
- /*
- * If it's an IPC, use the pipe handler.
- */
-
- if (IS_IPC(conn)) {
- if (lp_nt_pipe_support())
- return do_nt_transact_create_pipe(conn, inbuf, outbuf, length,
- bufsize, ppsetup, ppparams, ppdata);
- else
- return(ERROR(ERRDOS,ERRbadaccess));
- }
-
- /*
- * Ensure minimum number of parameters sent.
- */
-
- if(total_parameter_count < 54) {
- DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)total_parameter_count));
- return(ERROR(ERRDOS,ERRbadaccess));
- }
-
- flags = IVAL(params,0);
- desired_access = IVAL(params,8);
- file_attributes = IVAL(params,20);
- share_access = IVAL(params,24);
- create_disposition = IVAL(params,28);
- create_options = IVAL(params,32);
- fname_len = MIN(((uint32)IVAL(params,44)),((uint32)sizeof(fname)-1));
- root_dir_fid = (uint16)IVAL(params,4);
- smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
-
- /*
- * We need to construct the open_and_X ofun value from the
- * NT values, as that's what our code is structured to accept.
- */
-
- if((smb_ofun = map_create_disposition( create_disposition )) == -1)
- return(ERROR(ERRDOS,ERRbadmem));
-
- /*
- * Get the file name.
- */
-
- if(root_dir_fid != 0) {
- /*
- * This filename is relative to a directory fid.
- */
-
- files_struct *dir_fsp = file_fsp(params,4);
- size_t dir_name_len;
-
- if(!dir_fsp)
- return(ERROR(ERRDOS,ERRbadfid));
-
- if(!dir_fsp->is_directory) {
- /*
- * Check to see if this is a mac fork of some kind.
- */
-
- get_filename_transact(&fname[0], params, 53,
- total_parameter_count - 53 - fname_len, fname_len);
-
- if( fname[0] == ':') {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_OBJECT_PATH_NOT_FOUND));
- }
-
- return(ERROR(ERRDOS,ERRbadfid));
- }
-
- /*
- * Copy in the base directory name.
- */
-
- pstrcpy( fname, dir_fsp->fsp_name );
- dir_name_len = strlen(fname);
-
- /*
- * Ensure it ends in a '\'.
- */
-
- if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
- pstrcat(fname, "\\");
- dir_name_len++;
- }
-
- /*
- * This next calculation can refuse a correct filename if we're dealing
- * with the Win2k unicode bug, but that would be rare. JRA.
- */
-
- if(fname_len + dir_name_len >= sizeof(pstring))
- return(ERROR(ERRSRV,ERRfilespecs));
-
- get_filename_transact(&fname[dir_name_len], params, 53,
- total_parameter_count - 53 - fname_len, fname_len);
-
- } else {
- get_filename_transact(&fname[0], params, 53,
- total_parameter_count - 53 - fname_len, fname_len);
- }
-
- /*
- * Now contruct the smb_open_mode value from the desired access
- * and the share access.
- */
-
- if((smb_open_mode = map_share_mode( &stat_open_only, fname, desired_access,
- share_access, file_attributes)) == -1)
- return(ERROR(ERRDOS,ERRbadaccess));
-
- oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
- oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
-
- /*
- * Check if POSIX semantics are wanted.
- */
-
- set_posix_case_semantics(file_attributes);
-
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
-
- unix_convert(fname,conn,0,&bad_path,NULL);
-
- unixmode = unix_mode(conn,smb_attr | aARCH, fname);
-
- /*
- * If it's a request for a directory open, deal with it separately.
- */
-
- if(create_options & FILE_DIRECTORY_FILE) {