📄 nttrans.c
字号:
fsp = file_fsp(params, 0); replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False; CHECK_FSP(fsp, conn); srvstr_get_path_wcard(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE, &status, &path_contains_wcard); if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); } status = rename_internals(conn, fsp->fsp_name, new_name, 0, replace_if_exists, path_contains_wcard); if (!NT_STATUS_IS_OK(status)) return ERROR_NT(status); /* * Rename was successful. */ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0); DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", fsp->fsp_name, new_name)); /* * Win2k needs a changenotify request response before it will * update after a rename.. */ process_pending_change_notify_queue((time_t)0); return -1;}/****************************************************************************** Fake up a completely empty SD.*******************************************************************************/static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd){ size_t sd_size; *ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size); if(!*ppsd) { DEBUG(0,("get_null_nt_acl: Unable to malloc space for security descriptor.\n")); sd_size = 0; } return sd_size;}/**************************************************************************** Reply to query a security descriptor.****************************************************************************/static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count){ char *params = *ppparams; char *data = *ppdata; prs_struct pd; SEC_DESC *psd = NULL; size_t sd_size; uint32 security_info_wanted; TALLOC_CTX *mem_ctx; files_struct *fsp = NULL; if(parameter_count < 8) { return ERROR_DOS(ERRDOS,ERRbadfunc); } fsp = file_fsp(params,0); if(!fsp) { return ERROR_DOS(ERRDOS,ERRbadfid); } security_info_wanted = IVAL(params,4); DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name, (unsigned int)security_info_wanted )); params = nttrans_realloc(ppparams, 4); if(params == NULL) { return ERROR_DOS(ERRDOS,ERRnomem); } if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) { DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n")); return ERROR_DOS(ERRDOS,ERRnomem); } /* * Get the permissions to return. */ if (!lp_nt_acl_support(SNUM(conn))) { sd_size = get_null_nt_acl(mem_ctx, &psd); } else { sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, security_info_wanted, &psd); } if (sd_size == 0) { talloc_destroy(mem_ctx); return(UNIXERROR(ERRDOS,ERRnoaccess)); } DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size)); SIVAL(params,0,(uint32)sd_size); if(max_data_count < sd_size) { send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL, params, 4, *ppdata, 0); talloc_destroy(mem_ctx); return -1; } /* * Allocate the data we will point this at. */ data = nttrans_realloc(ppdata, sd_size); if(data == NULL) { talloc_destroy(mem_ctx); return ERROR_DOS(ERRDOS,ERRnomem); } /* * Init the parse struct we will marshall into. */ prs_init(&pd, 0, mem_ctx, MARSHALL); /* * Setup the prs_struct to point at the memory we just * allocated. */ prs_give_memory( &pd, data, (uint32)sd_size, False); /* * Finally, linearize into the outgoing buffer. */ if(!sec_io_desc( "sd data", &psd, &pd, 1)) { DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \security descriptor.\n")); /* * Return access denied for want of a better error message.. */ talloc_destroy(mem_ctx); return(UNIXERROR(ERRDOS,ERRnoaccess)); } /* * Now we can delete the security descriptor. */ talloc_destroy(mem_ctx); send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 4, data, (int)sd_size); return -1;}/**************************************************************************** Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.****************************************************************************/static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count){ char *params= *ppparams; char *data = *ppdata; files_struct *fsp = NULL; uint32 security_info_sent = 0; NTSTATUS nt_status; if(parameter_count < 8) { return ERROR_DOS(ERRDOS,ERRbadfunc); } if((fsp = file_fsp(params,0)) == NULL) { return ERROR_DOS(ERRDOS,ERRbadfid); } if(!lp_nt_acl_support(SNUM(conn))) { goto done; } security_info_sent = IVAL(params,4); DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name, (unsigned int)security_info_sent )); if (data_count == 0) { return ERROR_DOS(ERRDOS, ERRnoaccess); } if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent))) { return ERROR_NT(nt_status); } done: send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0); return -1;} /**************************************************************************** Reply to NT IOCTL****************************************************************************/static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count){ uint32 function; uint16 fidnum; files_struct *fsp; uint8 isFSctl; uint8 compfilter; static BOOL logged_message; char *pdata = *ppdata; if (setup_count != 8) { DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count)); return ERROR_NT(NT_STATUS_NOT_SUPPORTED); } function = IVAL(*ppsetup, 0); fidnum = SVAL(*ppsetup, 4); isFSctl = CVAL(*ppsetup, 6); compfilter = CVAL(*ppsetup, 7); DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", function, fidnum, isFSctl, compfilter)); fsp=file_fsp(*ppsetup, 4); /* this check is done in each implemented function case for now because I don't want to break anything... --metze FSP_BELONGS_CONN(fsp,conn);*/ switch (function) { case FSCTL_SET_SPARSE: /* pretend this succeeded - tho strictly we should mark the file sparse (if the local fs supports it) so we can know if we need to pre-allocate or not */ DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum)); send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0); return -1; case FSCTL_0x000900C0: /* pretend this succeeded - don't know what this really is but works ok like this --metze */ DEBUG(10,("FSCTL_0x000900C0: called on FID[0x%04X](but not implemented)\n",fidnum)); send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0); return -1; case FSCTL_GET_REPARSE_POINT: /* pretend this fail - my winXP does it like this * --metze */ DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum)); send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0); return -1; case FSCTL_SET_REPARSE_POINT: /* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case. * --metze */ DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum)); send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0); return -1; case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/ { /* * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots) * and return their volume names. If max_data_count is 16, then it is just * asking for the number of volumes and length of the combined names. * * pdata is the data allocated by our caller, but that uses * total_data_count (which is 0 in our case) rather than max_data_count. * Allocate the correct amount and return the pointer to let * it be deallocated when we return. */ SHADOW_COPY_DATA *shadow_data = NULL; TALLOC_CTX *shadow_mem_ctx = NULL; BOOL labels = False; uint32 labels_data_count = 0; uint32 i; char *cur_pdata; FSP_BELONGS_CONN(fsp,conn); if (max_data_count < 16) { DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n", max_data_count)); return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } if (max_data_count > 16) { labels = True; } shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA"); if (shadow_mem_ctx == NULL) { DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n")); return ERROR_NT(NT_STATUS_NO_MEMORY); } shadow_data = TALLOC_ZERO_P(shadow_mem_ctx,SHADOW_COPY_DATA); if (shadow_data == NULL) { DEBUG(0,("talloc_zero() failed!\n")); talloc_destroy(shadow_mem_ctx); return ERROR_NT(NT_STATUS_NO_MEMORY); } shadow_data->mem_ctx = shadow_mem_ctx; /* * Call the VFS routine to actually do the work. */ if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) { talloc_destroy(shadow_data->mem_ctx); if (errno == ENOSYS) { DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n", conn->connectpath)); return ERROR_NT(NT_STATUS_NOT_SUPPORTED); } else { DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n", conn->connectpath)); return ERROR_NT(NT_STATUS_UNSUCCESSFUL); } } labels_data_count = (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))+2; if (!labels) { data_count = 16; } else { data_count = 12+labels_data_count+4; } if (max_data_count<data_count) { DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n", max_data_count,data_count)); talloc_destroy(shadow_data->mem_ctx); return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL); } pdata = nttrans_realloc(ppdata, data_count); if (pdata == NULL) { talloc_destroy(shadow_data->mem_ctx); return ERROR_NT(NT_STATUS_NO_MEMORY); } cur_pdata = pdata; /* num_volumes 4 bytes */ SIVAL(pdata,0,shadow_data->num_volumes); if (labels) { /* num_labels 4 bytes */ SIVAL(pdata,4,shadow_data->num_volumes); } /* needed_data_count 4 bytes */ SIVAL(pdata,8,labels_data_count); cur_pdata+=12; DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n", shadow_data->num_volumes,fsp->fsp_name)); if (labels && shadow_data->labels) { for (i=0;i<shadow_data->num_volumes;i++) { srvstr_push(outbuf, cur_pdata, shadow_data->labels[i], 2*sizeof(SHADOW_COPY_LABEL), STR_UNICODE|STR_TERMINATE); cur_pdata+=2*sizeof(SHADOW_COPY_LABEL); DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i])); } } talloc_destroy(shadow_data->mem_ctx); send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, pdata, data_count); return -1; } case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */ { /* pretend this succeeded - * * we have to send back a list with all files owned by this SID * * but I have to check that --metze */ DOM_SID sid; uid_t uid; size_t sid_len = MIN(data_count-4,SID_MAX_SIZE); DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum)); FSP_BELONGS_CONN(fsp,conn); /* unknown 4 bytes: this is not the length of the sid :-( */ /*unknown = IVAL(pdata,0);*/ sid_parse(pdata+4,sid_len,&sid); DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid))); if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &uid))) { DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n", sid_string_static(&sid),(unsigned long)sid_len)); uid = (-1); } /* we can take a look at the find source :-) * * find ./ -uid $uid -name '*' is what we need here * * * and send 4bytes len and then NULL terminated unicode strings * for each file * * but I don't know how to deal with the paged results * (maybe we can hang the result anywhere in the fsp struct) * * we don't send all files at once * and at the next we should *not* start from the beginning, * so we have to cache the result * * --metze */ /* this works for now... */ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0); return -1; } default: if (!logged_message) { logged_message = True; /* Only print this once... */ DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n", function)); } } return ERROR_NT(NT_STATUS_NOT_SUPPORTED);}#ifdef HAVE_SYS_QUOTAS/**************************************************************************** Reply to get user quota ****************************************************************************/static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count){ NTSTATUS nt_status = NT_STATUS_OK; char *params = *ppparams; char *pdata = *ppda
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -