Changeset 862 for trunk/server/source3/smbd
- Timestamp:
- May 13, 2014, 11:39:04 AM (11 years ago)
- Location:
- trunk/server
- Files:
-
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 860
- Property svn:mergeinfo changed
-
trunk/server/source3/smbd/conn.c
r751 r862 482 482 DEBUG(1,("Forcing close of all shares\n")); 483 483 conn_close_all(sconn); 484 return;484 goto done; 485 485 } 486 486 … … 513 513 } 514 514 } 515 } 515 516 done: 517 518 change_to_root_user(); 519 reload_services(msg, -1, true); 520 } -
trunk/server/source3/smbd/dir.c
r751 r862 50 50 unsigned int name_cache_index; 51 51 unsigned int file_number; 52 files_struct *fsp; /* Back pointer to containing fsp, only 53 set from OpenDir_fsp(). */ 52 54 }; 53 55 … … 591 593 { 592 594 if (fsp->dptr) { 593 /* 594 * Ugly hack. We have defined fdopendir to return ENOSYS if dirfd also isn't 595 * present. I hate Solaris. JRA. 596 */ 597 #ifdef HAVE_DIRFD 598 if (fsp->fh->fd != -1 && 599 fsp->dptr->dir_hnd && 600 dirfd(fsp->dptr->dir_hnd->dir)) { 601 /* The call below closes the underlying fd. */ 602 fsp->fh->fd = -1; 603 } 604 #endif 595 /* 596 * The destructor for the struct smb_Dir 597 * (fsp->dptr->dir_hnd) now handles 598 * all resource deallocation. 599 */ 605 600 dptr_close_internal(fsp->dptr); 606 601 fsp->dptr = NULL; … … 942 937 { 943 938 connection_struct *conn = dirptr->conn; 944 bool needslash; 939 size_t slashlen; 940 size_t pathlen; 945 941 946 942 *_smb_fname = NULL; 947 943 *_mode = 0; 948 944 949 needslash = ( dirptr->path[strlen(dirptr->path) -1] != '/'); 945 pathlen = strlen(dirptr->path); 946 slashlen = ( dirptr->path[pathlen-1] != '/') ? 1 : 0; 950 947 951 948 while (true) { … … 991 988 } 992 989 993 pathreal = talloc_asprintf(ctx, "%s%s%s", 994 dirptr->path, 995 needslash?"/":"", 996 dname); 990 /* 991 * This used to be 992 * pathreal = talloc_asprintf(ctx, "%s%s%s", dirptr->path, 993 * needslash?"/":"", dname); 994 * but this was measurably slower than doing the memcpy. 995 */ 996 997 pathreal = talloc_array( 998 ctx, char, 999 pathlen + slashlen + talloc_get_size(dname)); 997 1000 if (!pathreal) { 998 1001 TALLOC_FREE(dname); … … 1000 1003 return false; 1001 1004 } 1005 1006 memcpy(pathreal, dirptr->path, pathlen); 1007 pathreal[pathlen] = '/'; 1008 memcpy(pathreal + slashlen + pathlen, dname, 1009 talloc_get_size(dname)); 1002 1010 1003 1011 /* Create smb_fname with NULL stream_name. */ … … 1333 1341 static int smb_Dir_destructor(struct smb_Dir *dirp) 1334 1342 { 1335 if (dirp->dir) { 1336 #ifdef HAVE_DIRFD 1337 if (dirp->conn->sconn) { 1338 files_struct *fsp = file_find_fd(dirp->conn->sconn, 1339 dirfd(dirp->dir)); 1340 if (fsp) { 1341 /* The call below closes the underlying fd. */ 1342 fsp->fh->fd = -1; 1343 if (dirp->dir != NULL) { 1344 SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); 1345 if (dirp->fsp != NULL) { 1346 /* 1347 * The SMB_VFS_CLOSEDIR above 1348 * closes the underlying fd inside 1349 * dirp->fsp. 1350 */ 1351 dirp->fsp->fh->fd = -1; 1352 if (dirp->fsp->dptr != NULL) { 1353 SMB_ASSERT(dirp->fsp->dptr->dir_hnd == dirp); 1354 dirp->fsp->dptr->dir_hnd = NULL; 1343 1355 } 1344 } 1345 #endif 1346 SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); 1356 dirp->fsp = NULL; 1357 } 1347 1358 } 1348 1359 if (dirp->conn->sconn && !dirp->conn->sconn->using_smb2) { … … 1428 1439 if (fsp->is_directory && fsp->fh->fd != -1) { 1429 1440 dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); 1430 if (dirp->dir == NULL) { 1441 if (dirp->dir != NULL) { 1442 dirp->fsp = fsp; 1443 } else { 1431 1444 DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " 1432 1445 "NULL (%s)\n", … … 1644 1657 *****************************************************************/ 1645 1658 1646 NTSTATUS can_delete_directory(struct connection_struct *conn, 1647 const char *dirname) 1659 NTSTATUS can_delete_directory_fsp(files_struct *fsp) 1648 1660 { 1649 1661 NTSTATUS status = NT_STATUS_OK; … … 1652 1664 char *talloced = NULL; 1653 1665 SMB_STRUCT_STAT st; 1654 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, 1655 dirname, NULL, 0); 1666 struct connection_struct *conn = fsp->conn; 1667 struct smb_Dir *dir_hnd = OpenDir_fsp(talloc_tos(), 1668 conn, 1669 fsp, 1670 NULL, 1671 0); 1656 1672 1657 1673 if (!dir_hnd) { … … 1668 1684 } 1669 1685 1670 if (!is_visible_file(conn, dirname, dname, &st, True)) {1686 if (!is_visible_file(conn, fsp->fsp_name->base_name, dname, &st, True)) { 1671 1687 TALLOC_FREE(talloced); 1672 1688 continue; 1673 1689 } 1674 1690 1675 DEBUG(10,("can_delete_directory : got name %s - can't delete\n",1691 DEBUG(10,("can_delete_directory_fsp: got name %s - can't delete\n", 1676 1692 dname )); 1677 1693 status = NT_STATUS_DIRECTORY_NOT_EMPTY; -
trunk/server/source3/smbd/dosmode.c
r745 r862 504 504 result = filter_mode_by_protocol(result); 505 505 506 /* 507 * Add in that it is a reparse point 508 */ 509 result |= FILE_ATTRIBUTE_REPARSE_POINT; 510 506 511 DEBUG(8,("dos_mode_msdfs returning ")); 507 512 -
trunk/server/source3/smbd/filename.c
r751 r862 446 446 if (errno == ENOENT) { 447 447 /* Optimization when creating a new file - only 448 the last component doesn't exist. */ 448 the last component doesn't exist. 449 NOTE : check_parent_exists() doesn't preserve errno. 450 */ 451 int saved_errno = errno; 449 452 status = check_parent_exists(ctx, 450 453 conn, … … 453 456 &dirpath, 454 457 &start); 458 errno = saved_errno; 455 459 if (!NT_STATUS_IS_OK(status)) { 456 460 goto fail; … … 525 529 * is in the last component and the client already 526 530 * sent the correct case. 531 * NOTE : check_parent_exists() doesn't preserve errno. 527 532 */ 533 int saved_errno = errno; 528 534 status = check_parent_exists(ctx, 529 535 conn, … … 532 538 &dirpath, 533 539 &start); 540 errno = saved_errno; 534 541 if (!NT_STATUS_IS_OK(status)) { 535 542 goto fail; … … 707 714 /* 708 715 * ENOENT/EACCESS are the only valid errors 709 * here. EACCESS needs handling here for 710 * "dropboxes", i.e. directories where users 711 * can only put stuff with permission -wx. 716 * here. 712 717 */ 713 if ((errno != 0) && (errno != ENOENT) 714 && (errno != EACCES)) { 718 if (errno == EACCES) { 719 if (ucf_flags & UCF_CREATING_FILE) { 720 /* 721 * This is the dropbox 722 * behaviour. A dropbox is a 723 * directory with only -wx 724 * permissions, so 725 * get_real_filename fails 726 * with EACCESS, it needs to 727 * list the directory. We 728 * nevertheless want to allow 729 * users creating a file. 730 */ 731 status = NT_STATUS_OBJECT_PATH_NOT_FOUND; 732 } else { 733 status = NT_STATUS_ACCESS_DENIED; 734 } 735 goto fail; 736 } 737 738 if ((errno != 0) && (errno != ENOENT)) { 715 739 /* 716 740 * ENOTDIR and ELOOP both map to -
trunk/server/source3/smbd/globals.h
r751 r862 163 163 uint16_t flags2, 164 164 unsigned int max_data_bytes, 165 size_t *fixed_portion, 165 166 char **ppdata, 166 167 unsigned int *pdata_size); … … 180 181 uint16_t flags2, 181 182 unsigned int max_data_bytes, 183 size_t *fixed_portion, 184 struct smb_filename *smb_fname, 182 185 char **ppdata, 183 186 int *ret_data_len); … … 647 650 uint32_t max_read; 648 651 uint32_t max_write; 649 bool compound_related_in_progress;650 652 } smb2; 651 653 }; -
trunk/server/source3/smbd/lanman.c
r751 r862 2629 2629 goto close_domain; 2630 2630 } 2631 if (rid.count != 1) { 2632 status = NT_STATUS_INVALID_NETWORK_RESPONSE; 2633 goto close_domain; 2634 } 2635 if (type.count != 1) { 2636 status = NT_STATUS_INVALID_NETWORK_RESPONSE; 2637 goto close_domain; 2638 } 2631 2639 2632 2640 if (type.ids[0] != SID_NAME_USER) { … … 2937 2945 2938 2946 return True; 2939 }2940 2941 /****************************************************************************2942 Set the user password.2943 *****************************************************************************/2944 2945 static bool api_SetUserPassword(struct smbd_server_connection *sconn,2946 connection_struct *conn,uint16 vuid,2947 char *param, int tpscnt,2948 char *data, int tdscnt,2949 int mdrcnt,int mprcnt,2950 char **rdata,char **rparam,2951 int *rdata_len,int *rparam_len)2952 {2953 char *np = get_safe_str_ptr(param,tpscnt,param,2);2954 char *p = NULL;2955 fstring user;2956 fstring pass1,pass2;2957 TALLOC_CTX *mem_ctx = talloc_tos();2958 NTSTATUS status, result;2959 struct rpc_pipe_client *cli = NULL;2960 struct policy_handle connect_handle, domain_handle, user_handle;2961 struct lsa_String domain_name;2962 struct dom_sid2 *domain_sid;2963 struct lsa_String names;2964 struct samr_Ids rids;2965 struct samr_Ids types;2966 struct samr_Password old_lm_hash;2967 struct samr_Password new_lm_hash;2968 int errcode = NERR_badpass;2969 uint32_t rid;2970 int encrypted;2971 int min_pwd_length;2972 struct dcerpc_binding_handle *b = NULL;2973 2974 /* Skip 2 strings. */2975 p = skip_string(param,tpscnt,np);2976 p = skip_string(param,tpscnt,p);2977 2978 if (!np || !p) {2979 return False;2980 }2981 2982 /* Do we have a string ? */2983 if (skip_string(param,tpscnt,p) == NULL) {2984 return False;2985 }2986 pull_ascii_fstring(user,p);2987 2988 p = skip_string(param,tpscnt,p);2989 if (!p) {2990 return False;2991 }2992 2993 memset(pass1,'\0',sizeof(pass1));2994 memset(pass2,'\0',sizeof(pass2));2995 /*2996 * We use 31 here not 32 as we're checking2997 * the last byte we want to access is safe.2998 */2999 if (!is_offset_safe(param,tpscnt,p,31)) {3000 return False;3001 }3002 memcpy(pass1,p,16);3003 memcpy(pass2,p+16,16);3004 3005 encrypted = get_safe_SVAL(param,tpscnt,p+32,0,-1);3006 if (encrypted == -1) {3007 errcode = W_ERROR_V(WERR_INVALID_PARAM);3008 goto out;3009 }3010 3011 min_pwd_length = get_safe_SVAL(param,tpscnt,p+34,0,-1);3012 if (min_pwd_length == -1) {3013 errcode = W_ERROR_V(WERR_INVALID_PARAM);3014 goto out;3015 }3016 3017 *rparam_len = 4;3018 *rparam = smb_realloc_limit(*rparam,*rparam_len);3019 if (!*rparam) {3020 return False;3021 }3022 3023 *rdata_len = 0;3024 3025 DEBUG(3,("Set password for <%s> (encrypted: %d, min_pwd_length: %d)\n",3026 user, encrypted, min_pwd_length));3027 3028 ZERO_STRUCT(connect_handle);3029 ZERO_STRUCT(domain_handle);3030 ZERO_STRUCT(user_handle);3031 3032 status = rpc_pipe_open_interface(mem_ctx, &ndr_table_samr.syntax_id,3033 conn->session_info,3034 &conn->sconn->client_id,3035 conn->sconn->msg_ctx,3036 &cli);3037 if (!NT_STATUS_IS_OK(status)) {3038 DEBUG(0,("api_SetUserPassword: could not connect to samr: %s\n",3039 nt_errstr(status)));3040 errcode = W_ERROR_V(ntstatus_to_werror(status));3041 goto out;3042 }3043 3044 b = cli->binding_handle;3045 3046 status = dcerpc_samr_Connect2(b, mem_ctx,3047 global_myname(),3048 SAMR_ACCESS_CONNECT_TO_SERVER |3049 SAMR_ACCESS_ENUM_DOMAINS |3050 SAMR_ACCESS_LOOKUP_DOMAIN,3051 &connect_handle,3052 &result);3053 if (!NT_STATUS_IS_OK(status)) {3054 errcode = W_ERROR_V(ntstatus_to_werror(status));3055 goto out;3056 }3057 if (!NT_STATUS_IS_OK(result)) {3058 errcode = W_ERROR_V(ntstatus_to_werror(result));3059 goto out;3060 }3061 3062 init_lsa_String(&domain_name, get_global_sam_name());3063 3064 status = dcerpc_samr_LookupDomain(b, mem_ctx,3065 &connect_handle,3066 &domain_name,3067 &domain_sid,3068 &result);3069 if (!NT_STATUS_IS_OK(status)) {3070 errcode = W_ERROR_V(ntstatus_to_werror(status));3071 goto out;3072 }3073 if (!NT_STATUS_IS_OK(result)) {3074 errcode = W_ERROR_V(ntstatus_to_werror(result));3075 goto out;3076 }3077 3078 status = dcerpc_samr_OpenDomain(b, mem_ctx,3079 &connect_handle,3080 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,3081 domain_sid,3082 &domain_handle,3083 &result);3084 if (!NT_STATUS_IS_OK(status)) {3085 errcode = W_ERROR_V(ntstatus_to_werror(status));3086 goto out;3087 }3088 if (!NT_STATUS_IS_OK(result)) {3089 errcode = W_ERROR_V(ntstatus_to_werror(result));3090 goto out;3091 }3092 3093 init_lsa_String(&names, user);3094 3095 status = dcerpc_samr_LookupNames(b, mem_ctx,3096 &domain_handle,3097 1,3098 &names,3099 &rids,3100 &types,3101 &result);3102 if (!NT_STATUS_IS_OK(status)) {3103 errcode = W_ERROR_V(ntstatus_to_werror(status));3104 goto out;3105 }3106 if (!NT_STATUS_IS_OK(result)) {3107 errcode = W_ERROR_V(ntstatus_to_werror(result));3108 goto out;3109 }3110 3111 if (rids.count != 1) {3112 errcode = W_ERROR_V(WERR_NO_SUCH_USER);3113 goto out;3114 }3115 if (rids.count != types.count) {3116 errcode = W_ERROR_V(WERR_INVALID_PARAM);3117 goto out;3118 }3119 if (types.ids[0] != SID_NAME_USER) {3120 errcode = W_ERROR_V(WERR_INVALID_PARAM);3121 goto out;3122 }3123 3124 rid = rids.ids[0];3125 3126 status = dcerpc_samr_OpenUser(b, mem_ctx,3127 &domain_handle,3128 SAMR_USER_ACCESS_CHANGE_PASSWORD,3129 rid,3130 &user_handle,3131 &result);3132 if (!NT_STATUS_IS_OK(status)) {3133 errcode = W_ERROR_V(ntstatus_to_werror(status));3134 goto out;3135 }3136 if (!NT_STATUS_IS_OK(result)) {3137 errcode = W_ERROR_V(ntstatus_to_werror(result));3138 goto out;3139 }3140 3141 if (encrypted == 0) {3142 E_deshash(pass1, old_lm_hash.hash);3143 E_deshash(pass2, new_lm_hash.hash);3144 } else {3145 ZERO_STRUCT(old_lm_hash);3146 ZERO_STRUCT(new_lm_hash);3147 memcpy(old_lm_hash.hash, pass1, MIN(strlen(pass1), 16));3148 memcpy(new_lm_hash.hash, pass1, MIN(strlen(pass2), 16));3149 }3150 3151 status = dcerpc_samr_ChangePasswordUser(b, mem_ctx,3152 &user_handle,3153 true, /* lm_present */3154 &old_lm_hash,3155 &new_lm_hash,3156 false, /* nt_present */3157 NULL, /* old_nt_crypted */3158 NULL, /* new_nt_crypted */3159 false, /* cross1_present */3160 NULL, /* nt_cross */3161 false, /* cross2_present */3162 NULL, /* lm_cross */3163 &result);3164 if (!NT_STATUS_IS_OK(status)) {3165 errcode = W_ERROR_V(ntstatus_to_werror(status));3166 goto out;3167 }3168 if (!NT_STATUS_IS_OK(result)) {3169 errcode = W_ERROR_V(ntstatus_to_werror(result));3170 goto out;3171 }3172 3173 errcode = NERR_Success;3174 out:3175 3176 if (b && is_valid_policy_hnd(&user_handle)) {3177 dcerpc_samr_Close(b, mem_ctx, &user_handle, &result);3178 }3179 if (b && is_valid_policy_hnd(&domain_handle)) {3180 dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);3181 }3182 if (b && is_valid_policy_hnd(&connect_handle)) {3183 dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);3184 }3185 3186 memset((char *)pass1,'\0',sizeof(fstring));3187 memset((char *)pass2,'\0',sizeof(fstring));3188 3189 SSVAL(*rparam,0,errcode);3190 SSVAL(*rparam,2,0); /* converter word */3191 return(True);3192 2947 } 3193 2948 … … 5785 5540 {"NetServerEnum3", RAP_NetServerEnum3, api_RNetServerEnum3}, /* anon OK */ 5786 5541 {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms}, 5787 {"SetUserPassword", RAP_WUserPasswordSet2, api_SetUserPassword},5788 5542 {"WWkstaUserLogon", RAP_WWkstaUserLogon, api_WWkstaUserLogon}, 5789 5543 {"PrintJobInfo", RAP_WPrintJobSetInfo, api_PrintJobInfo}, -
trunk/server/source3/smbd/mangle_hash2.c
r745 r862 627 627 if (((unsigned int)name[0]) > 128 && (name[1] != 0)) { 628 628 /* Possible start of mb character. */ 629 char mbc[2]; 629 size_t size = 0; 630 (void)next_codepoint(name, &size); 630 631 /* 631 632 * Note that if CH_UNIX is utf8 a string may be 3 … … 635 636 * JRA. 636 637 */ 637 if ( convert_string(CH_UNIX, CH_UTF16LE, name, 2, mbc, 2, False) == 2) {638 /* Was a goodmb string. */639 name += 2;638 if (size > 1) { 639 /* Was a mb string. */ 640 name += size; 640 641 continue; 641 642 } -
trunk/server/source3/smbd/msdfs.c
r751 r862 975 975 DEBUG(3,("get_referred_path: No valid referrals for path %s\n", 976 976 dfs_path)); 977 if (NT_STATUS_IS_OK(status)) { 978 /* 979 * We are in an error path here (we 980 * know it's not a DFS path), but 981 * dfs_path_lookup() can return 982 * NT_STATUS_OK. Ensure we always 983 * return a valid error code. 984 * 985 * #9588 - ACLs are not inherited to directories 986 * for DFS shares. 987 */ 988 status = NT_STATUS_NOT_FOUND; 989 } 977 990 goto err_exit; 978 991 } -
trunk/server/source3/smbd/nttrans.c
r751 r862 537 537 req->flags2 & FLAGS2_DFS_PATHNAMES, 538 538 fname, 539 0, 539 (create_disposition == FILE_CREATE) 540 ? UCF_CREATING_FILE : 0, 540 541 NULL, 541 542 &smb_fname); … … 886 887 /* Ensure we have at least one thing set. */ 887 888 if ((security_info_sent & (SECINFO_OWNER|SECINFO_GROUP|SECINFO_DACL|SECINFO_SACL)) == 0) { 888 if (security_info_sent & SECINFO_LABEL) { 889 /* Only consider SECINFO_LABEL if no other 890 bits are set. Just like W2K3 we don't 891 store this. */ 892 return NT_STATUS_OK; 893 } 894 return NT_STATUS_INVALID_PARAMETER; 889 /* Just like W2K3 */ 890 return NT_STATUS_OK; 895 891 } 896 892 … … 990 986 break; 991 987 } 988 989 /* Integer wrap protection for the increment. */ 990 if (offset + next_offset < offset) { 991 break; 992 } 993 992 994 offset += next_offset; 995 996 /* Integer wrap protection for while loop. */ 997 if (offset + 4 < offset) { 998 break; 999 } 1000 993 1001 } 994 1002 … … 1159 1167 req->flags2 & FLAGS2_DFS_PATHNAMES, 1160 1168 fname, 1161 0, 1169 (create_disposition == FILE_CREATE) 1170 ? UCF_CREATING_FILE : 0, 1162 1171 NULL, 1163 1172 &smb_fname); -
trunk/server/source3/smbd/open.c
r751 r862 59 59 } 60 60 61 /* 62 * If we can access the path to this file, by 63 * default we have FILE_READ_ATTRIBUTES from the 64 * containing directory. See the section: 65 * "Algorithm to Check Access to an Existing File" 66 * in MS-FSA.pdf. 67 */ 61 68 return se_access_check(sd, 62 69 token, … … 143 150 144 151 return status; 152 } 153 154 /**************************************************************************** 155 Ensure when opening a base file for a stream open that we have permissions 156 to do so given the access mask on the base file. 157 ****************************************************************************/ 158 159 static NTSTATUS check_base_file_access(struct connection_struct *conn, 160 struct smb_filename *smb_fname, 161 uint32_t access_mask) 162 { 163 uint32_t access_granted = 0; 164 NTSTATUS status; 165 166 status = smbd_calculate_access_mask(conn, smb_fname, 167 false, 168 access_mask, 169 &access_mask); 170 if (!NT_STATUS_IS_OK(status)) { 171 DEBUG(10, ("smbd_calculate_access_mask " 172 "on file %s returned %s\n", 173 smb_fname_str_dbg(smb_fname), 174 nt_errstr(status))); 175 return status; 176 } 177 178 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) { 179 uint32_t dosattrs; 180 if (!CAN_WRITE(conn)) { 181 return NT_STATUS_ACCESS_DENIED; 182 } 183 dosattrs = dos_mode(conn, smb_fname); 184 if (IS_DOS_READONLY(dosattrs)) { 185 return NT_STATUS_ACCESS_DENIED; 186 } 187 } 188 189 190 return smbd_check_open_rights(conn, 191 smb_fname, 192 access_mask, 193 &access_granted); 145 194 } 146 195 … … 1417 1466 } 1418 1467 1419 access_mask = access_granted; 1468 /* 1469 * If we can access the path to this file, by 1470 * default we have FILE_READ_ATTRIBUTES from the 1471 * containing directory. See the section. 1472 * "Algorithm to Check Access to an Existing File" 1473 * in MS-FSA.pdf. 1474 */ 1475 access_mask = access_granted | FILE_READ_ATTRIBUTES; 1420 1476 } else { 1421 1477 access_mask = FILE_GENERIC_ALL; … … 1989 2045 /* 1990 2046 * If we're returning a share violation, ensure we 1991 * cope with the braindead 1 second delay .2047 * cope with the braindead 1 second delay (SMB1 only). 1992 2048 */ 1993 2049 1994 2050 if (!(oplock_request & INTERNAL_OPEN_ONLY) && 2051 !conn->sconn->using_smb2 && 1995 2052 lp_defer_sharing_violations()) { 1996 2053 struct timeval timeout; … … 2753 2810 mtimespec = smb_dname->st.st_ex_mtime; 2754 2811 2755 /* Temporary access mask used to open the directory fd. */2756 fsp->access_mask = FILE_READ_DATA | FILE_READ_ATTRIBUTES; 2812 fsp->access_mask = access_mask; 2813 2757 2814 #ifdef O_DIRECTORY 2758 2815 status = fd_open(conn, fsp, O_RDONLY|O_DIRECTORY, 0); … … 3213 3270 DEBUG(10, ("Unable to stat stream: %s\n", 3214 3271 smb_fname_str_dbg(smb_fname_base))); 3272 } else { 3273 /* 3274 * https://bugzilla.samba.org/show_bug.cgi?id=10229 3275 * We need to check if the requested access mask 3276 * could be used to open the underlying file (if 3277 * it existed), as we're passing in zero for the 3278 * access mask to the base filename. 3279 */ 3280 status = check_base_file_access(conn, 3281 smb_fname_base, 3282 access_mask); 3283 3284 if (!NT_STATUS_IS_OK(status)) { 3285 DEBUG(10, ("Permission check " 3286 "for base %s failed: " 3287 "%s\n", smb_fname->base_name, 3288 nt_errstr(status))); 3289 goto fail; 3290 } 3215 3291 } 3216 3292 -
trunk/server/source3/smbd/oplock_linux.c
r751 r862 76 76 { 77 77 int ret; 78 int saved_errno; 79 80 /* 81 * Ensure the lease owner is root to allow 82 * correct delivery of lease-break signals. 83 */ 84 85 become_root(); 78 86 79 87 /* First set the signal handler. */ 80 88 if (linux_set_lease_sighandler(fd) == -1) { 81 return -1; 89 saved_errno = errno; 90 ret = -1; 91 goto out; 82 92 } 83 93 ret = fcntl(fd, F_SETLEASE, leasetype); 84 if (ret == -1 && errno == EACCES) { 85 set_effective_capability(LEASE_CAPABILITY); 86 /* 87 * Bug 8974 - work around Linux kernel bug 88 * https://bugzilla.kernel.org/show_bug.cgi?id=43336. 89 * "fcntl(F_SETLEASE) resets signal number when 90 * called multiple times" 91 */ 92 if (linux_set_lease_sighandler(fd) == -1) { 93 return -1; 94 } 95 ret = fcntl(fd, F_SETLEASE, leasetype); 96 } 97 94 if (ret == -1) { 95 saved_errno = errno; 96 } 97 98 out: 99 100 unbecome_root(); 101 102 if (ret == -1) { 103 errno = saved_errno; 104 } 98 105 return ret; 99 106 } -
trunk/server/source3/smbd/posix_acls.c
r751 r862 1373 1373 if (pace->type == SMB_ACL_USER_OBJ) { 1374 1374 1375 if (setting_acl && !is_default_acl) { 1375 if (setting_acl) { 1376 /* 1377 * Ensure we have default parameters for the 1378 * user (owner) even on default ACLs. 1379 */ 1376 1380 apply_default_perms(params, is_directory, pace, S_IRUSR); 1377 1381 } … … 1453 1457 } 1454 1458 1455 if (!is_default_acl) { 1456 apply_default_perms(params, is_directory, pace, S_IRUSR); 1457 } 1459 /* 1460 * Ensure we have default parameters for the 1461 * user (owner) even on default ACLs. 1462 */ 1463 apply_default_perms(params, is_directory, pace, S_IRUSR); 1458 1464 } else { 1459 1465 pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR); -
trunk/server/source3/smbd/process.c
r751 r862 155 155 } 156 156 157 len = smb_len (buf_out) + 4;157 len = smb_len_large(buf_out) + 4; 158 158 159 159 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten); … … 923 923 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te)); 924 924 return result; 925 }926 927 static void smbd_sig_term_handler(struct tevent_context *ev,928 struct tevent_signal *se,929 int signum,930 int count,931 void *siginfo,932 void *private_data)933 {934 exit_server_cleanly("termination signal");935 }936 937 void smbd_setup_sig_term_handler(void)938 {939 struct tevent_signal *se;940 941 se = tevent_add_signal(smbd_event_context(),942 smbd_event_context(),943 SIGTERM, 0,944 smbd_sig_term_handler,945 NULL);946 if (!se) {947 exit_server("failed to setup SIGTERM handler");948 }949 }950 951 static void smbd_sig_hup_handler(struct tevent_context *ev,952 struct tevent_signal *se,953 int signum,954 int count,955 void *siginfo,956 void *private_data)957 {958 struct messaging_context *msg_ctx = talloc_get_type_abort(959 private_data, struct messaging_context);960 change_to_root_user();961 DEBUG(1,("Reloading services after SIGHUP\n"));962 reload_services(msg_ctx, smbd_server_conn->sock, False);963 if (am_parent) {964 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);965 }966 }967 968 void smbd_setup_sig_hup_handler(struct tevent_context *ev,969 struct messaging_context *msg_ctx)970 {971 struct tevent_signal *se;972 973 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,974 msg_ctx);975 if (!se) {976 exit_server("failed to setup SIGHUP handler");977 }978 925 } 979 926 … … 2034 1981 */ 2035 1982 req->chain_outbuf = TALLOC_REALLOC_ARRAY( 2036 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4); 1983 req, req->outbuf, uint8_t, 1984 smb_len_large(req->outbuf) + 4); 2037 1985 if (req->chain_outbuf == NULL) { 2038 1986 smb_panic("talloc failed"); -
trunk/server/source3/smbd/proto.h
r751 r862 770 770 /* The following definitions come from smbd/process.c */ 771 771 772 void smbd_setup_sig_term_handler(void);773 void smbd_setup_sig_hup_handler(struct tevent_context *ev,774 struct messaging_context *msg_ctx);775 772 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer, 776 773 bool no_signing, uint32_t seqnum, … … 981 978 void reload_printers(struct tevent_context *ev, 982 979 struct messaging_context *msg_ctx); 980 void reload_printers_full(struct tevent_context *ev, 981 struct messaging_context *msg_ctx); 983 982 bool reload_services(struct messaging_context *msg_ctx, int smb_sock, 984 983 bool test); 985 void reload_pcap_change_notify(struct tevent_context *ev,986 struct messaging_context *msg_ctx);987 984 void exit_server(const char *const explanation); 988 985 void exit_server_cleanly(const char *const explanation); -
trunk/server/source3/smbd/reply.c
r751 r862 1749 1749 } 1750 1750 1751 if (!map_open_params_to_ntcreate(fname, deny_mode, 1752 OPENX_FILE_EXISTS_OPEN, &access_mask, 1753 &share_mode, &create_disposition, 1754 &create_options, &private_flags)) { 1755 reply_force_doserror(req, ERRDOS, ERRbadaccess); 1756 goto out; 1757 } 1758 1751 1759 status = filename_convert(ctx, 1752 1760 conn, 1753 1761 req->flags2 & FLAGS2_DFS_PATHNAMES, 1754 1762 fname, 1755 0, 1763 (create_disposition == FILE_CREATE) 1764 ? UCF_CREATING_FILE : 0, 1756 1765 NULL, 1757 1766 &smb_fname); … … 1764 1773 } 1765 1774 reply_nterror(req, status); 1766 goto out;1767 }1768 1769 if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,1770 OPENX_FILE_EXISTS_OPEN, &access_mask,1771 &share_mode, &create_disposition,1772 &create_options, &private_flags)) {1773 reply_force_doserror(req, ERRDOS, ERRbadaccess);1774 1775 goto out; 1775 1776 } … … 1924 1925 } 1925 1926 1927 if (!map_open_params_to_ntcreate(fname, deny_mode, 1928 smb_ofun, 1929 &access_mask, &share_mode, 1930 &create_disposition, 1931 &create_options, 1932 &private_flags)) { 1933 reply_force_doserror(req, ERRDOS, ERRbadaccess); 1934 goto out; 1935 } 1936 1926 1937 status = filename_convert(ctx, 1927 1938 conn, 1928 1939 req->flags2 & FLAGS2_DFS_PATHNAMES, 1929 1940 fname, 1930 0, 1941 (create_disposition == FILE_CREATE) 1942 ? UCF_CREATING_FILE : 0, 1931 1943 NULL, 1932 1944 &smb_fname); … … 1939 1951 } 1940 1952 reply_nterror(req, status); 1941 goto out;1942 }1943 1944 if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,1945 smb_ofun,1946 &access_mask, &share_mode,1947 &create_disposition,1948 &create_options,1949 &private_flags)) {1950 reply_force_doserror(req, ERRDOS, ERRbadaccess);1951 1953 goto out; 1952 1954 } … … 2146 2148 req->flags2 & FLAGS2_DFS_PATHNAMES, 2147 2149 fname, 2148 0,2150 UCF_CREATING_FILE, 2149 2151 NULL, 2150 2152 &smb_fname); … … 2240 2242 connection_struct *conn = req->conn; 2241 2243 struct smb_filename *smb_fname = NULL; 2244 char *wire_name = NULL; 2242 2245 char *fname = NULL; 2243 2246 uint32 fattr; 2244 2247 files_struct *fsp; 2245 2248 int oplock_request; 2246 int tmpfd;2247 2249 char *s; 2248 2250 NTSTATUS status; 2251 int i; 2249 2252 TALLOC_CTX *ctx = talloc_tos(); 2250 2253 … … 2259 2262 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf); 2260 2263 2261 srvstr_get_path_req(ctx, req, & fname, (const char *)req->buf+1,2264 srvstr_get_path_req(ctx, req, &wire_name, (const char *)req->buf+1, 2262 2265 STR_TERMINATE, &status); 2263 2266 if (!NT_STATUS_IS_OK(status)) { … … 2265 2268 goto out; 2266 2269 } 2267 if (*fname) { 2268 fname = talloc_asprintf(ctx, 2269 "%s/TMXXXXXX", 2270 fname); 2271 } else { 2272 fname = talloc_strdup(ctx, "TMXXXXXX"); 2273 } 2274 2275 if (!fname) { 2276 reply_nterror(req, NT_STATUS_NO_MEMORY); 2277 goto out; 2278 } 2279 2280 status = filename_convert(ctx, conn, 2270 2271 for (i = 0; i < 10; i++) { 2272 if (*wire_name) { 2273 fname = talloc_asprintf(ctx, 2274 "%s/TMP%s", 2275 wire_name, 2276 generate_random_str_list(ctx, 5, "0123456789")); 2277 } else { 2278 fname = talloc_asprintf(ctx, 2279 "TMP%s", 2280 generate_random_str_list(ctx, 5, "0123456789")); 2281 } 2282 2283 if (!fname) { 2284 reply_nterror(req, NT_STATUS_NO_MEMORY); 2285 goto out; 2286 } 2287 2288 status = filename_convert(ctx, conn, 2281 2289 req->flags2 & FLAGS2_DFS_PATHNAMES, 2282 2290 fname, 2283 0,2291 UCF_CREATING_FILE, 2284 2292 NULL, 2285 2293 &smb_fname); 2286 if (!NT_STATUS_IS_OK(status)) {2287 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {2288 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,2294 if (!NT_STATUS_IS_OK(status)) { 2295 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 2296 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, 2289 2297 ERRSRV, ERRbadpath); 2298 goto out; 2299 } 2300 reply_nterror(req, status); 2290 2301 goto out; 2291 2302 } 2303 2304 /* Create the file. */ 2305 status = SMB_VFS_CREATE_FILE( 2306 conn, /* conn */ 2307 req, /* req */ 2308 0, /* root_dir_fid */ 2309 smb_fname, /* fname */ 2310 FILE_GENERIC_READ | FILE_GENERIC_WRITE, /* access_mask */ 2311 FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */ 2312 FILE_CREATE, /* create_disposition*/ 2313 0, /* create_options */ 2314 fattr, /* file_attributes */ 2315 oplock_request, /* oplock_request */ 2316 0, /* allocation_size */ 2317 0, /* private_flags */ 2318 NULL, /* sd */ 2319 NULL, /* ea_list */ 2320 &fsp, /* result */ 2321 NULL); /* pinfo */ 2322 2323 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { 2324 TALLOC_FREE(fname); 2325 TALLOC_FREE(smb_fname); 2326 continue; 2327 } 2328 2329 if (!NT_STATUS_IS_OK(status)) { 2330 if (open_was_deferred(req->mid)) { 2331 /* We have re-scheduled this call. */ 2332 goto out; 2333 } 2334 reply_openerror(req, status); 2335 goto out; 2336 } 2337 2338 break; 2339 } 2340 2341 if (i == 10) { 2342 /* Collision after 10 times... */ 2292 2343 reply_nterror(req, status); 2293 goto out;2294 }2295 2296 tmpfd = mkstemp(smb_fname->base_name);2297 if (tmpfd == -1) {2298 reply_nterror(req, map_nt_error_from_unix(errno));2299 goto out;2300 }2301 2302 SMB_VFS_STAT(conn, smb_fname);2303 2304 /* We should fail if file does not exist. */2305 status = SMB_VFS_CREATE_FILE(2306 conn, /* conn */2307 req, /* req */2308 0, /* root_dir_fid */2309 smb_fname, /* fname */2310 FILE_GENERIC_READ | FILE_GENERIC_WRITE, /* access_mask */2311 FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */2312 FILE_OPEN, /* create_disposition*/2313 0, /* create_options */2314 fattr, /* file_attributes */2315 oplock_request, /* oplock_request */2316 0, /* allocation_size */2317 0, /* private_flags */2318 NULL, /* sd */2319 NULL, /* ea_list */2320 &fsp, /* result */2321 NULL); /* pinfo */2322 2323 /* close fd from mkstemp() */2324 close(tmpfd);2325 2326 if (!NT_STATUS_IS_OK(status)) {2327 if (open_was_deferred(req->mid)) {2328 /* We have re-scheduled this call. */2329 goto out;2330 }2331 reply_openerror(req, status);2332 2344 goto out; 2333 2345 } … … 2370 2382 out: 2371 2383 TALLOC_FREE(smb_fname); 2384 TALLOC_FREE(fname); 2385 TALLOC_FREE(wire_name); 2372 2386 END_PROFILE(SMBctemp); 2373 2387 return; … … 3137 3151 START_PROFILE(SMBreadbraw); 3138 3152 3139 if (srv_is_signing_active(sconn) || 3140 is_encrypted_packet(req->inbuf)) { 3153 if (srv_is_signing_active(sconn) || req->encrypted) { 3141 3154 exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - " 3142 3155 "raw reads/writes are disallowed."); … … 3531 3544 int saved_errno = 0; 3532 3545 3533 if(fsp_stat(fsp) == -1) {3534 reply_nterror(req, map_nt_error_from_unix(errno));3535 return;3536 }3537 3538 3546 init_strict_lock_struct(fsp, (uint64_t)req->smbpid, 3539 3547 (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK, … … 3543 3551 reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); 3544 3552 return; 3545 }3546 3547 if (!S_ISREG(fsp->fsp_name->st.st_ex_mode) ||3548 (startpos > fsp->fsp_name->st.st_ex_size)3549 || (smb_maxcnt > (fsp->fsp_name->st.st_ex_size - startpos))) {3550 /*3551 * We already know that we would do a short read, so don't3552 * try the sendfile() path.3553 */3554 goto nosendfile_read;3555 3553 } 3556 3554 … … 3562 3560 3563 3561 if (!req_is_in_chain(req) && 3564 ! is_encrypted_packet(req->inbuf)&& (fsp->base_fsp == NULL) &&3562 !req->encrypted && (fsp->base_fsp == NULL) && 3565 3563 (fsp->wcp == NULL) && 3566 3564 lp_use_sendfile(SNUM(conn), req->sconn->smb1.signing_state) ) { 3567 3565 uint8 headerbuf[smb_size + 12 * 2]; 3568 3566 DATA_BLOB header; 3567 3568 if(fsp_stat(fsp) == -1) { 3569 reply_nterror(req, map_nt_error_from_unix(errno)); 3570 goto strict_unlock; 3571 } 3572 3573 if (!S_ISREG(fsp->fsp_name->st.st_ex_mode) || 3574 (startpos > fsp->fsp_name->st.st_ex_size) || 3575 (smb_maxcnt > (fsp->fsp_name->st.st_ex_size - startpos))) { 3576 /* 3577 * We already know that we would do a short read, so don't 3578 * try the sendfile() path. 3579 */ 3580 goto nosendfile_read; 3581 } 3569 3582 3570 3583 /* … … 3766 3779 } 3767 3780 /* We currently don't do this on signed or sealed data. */ 3768 if (srv_is_signing_active(req->sconn) || 3769 is_encrypted_packet(req->inbuf)) { 3781 if (srv_is_signing_active(req->sconn) || req->encrypted) { 3770 3782 reply_nterror(req, NT_STATUS_NOT_SUPPORTED); 3771 3783 END_PROFILE(SMBreadX); … … 5530 5542 req->flags2 & FLAGS2_DFS_PATHNAMES, 5531 5543 directory, 5532 0,5544 UCF_CREATING_FILE, 5533 5545 NULL, 5534 5546 &smb_dname); … … 6195 6207 smb_fname_str_dbg(smb_fname_dst))); 6196 6208 6197 if (!lp_posix_pathnames() && 6209 if (!fsp->is_directory && 6210 !lp_posix_pathnames() && 6198 6211 (lp_map_archive(SNUM(conn)) || 6199 6212 lp_store_dos_attributes(SNUM(conn)))) { -
trunk/server/source3/smbd/server.c
r845 r862 21 21 along with this program. If not, see <http://www.gnu.org/licenses/>. 22 22 */ 23 #ifdef __OS2__24 #define INCL_DOSEXCEPTIONS25 #define INCL_DOSPROCESS26 #define INCL_DOSMODULEMGR27 #define INCL_LOADEXCEPTQ28 #define INCL_FORKEXCEPTQ29 #include "os2.h"30 #include "exceptq.h"31 #undef FILE_CREATE32 #undef FILE_OPEN33 #endif34 23 35 24 #include "includes.h" … … 120 109 change_to_root_user(); 121 110 reload_services(msg, smbd_server_conn->sock, False); 122 if (am_parent) { 123 pcap_cache_reload(ev_ctx, msg, 124 &reload_pcap_change_notify); 125 } 111 /* printer reload triggered by background printing process */ 126 112 } 127 113 … … 143 129 reload_printers(ev_ctx, msg); 144 130 } 131 132 static void smbd_sig_term_handler(struct tevent_context *ev, 133 struct tevent_signal *se, 134 int signum, 135 int count, 136 void *siginfo, 137 void *private_data) 138 { 139 exit_server_cleanly("termination signal"); 140 } 141 142 static void smbd_setup_sig_term_handler(void) 143 { 144 struct tevent_signal *se; 145 146 se = tevent_add_signal(smbd_event_context(), 147 smbd_event_context(), 148 SIGTERM, 0, 149 smbd_sig_term_handler, 150 NULL); 151 if (!se) { 152 exit_server("failed to setup SIGTERM handler"); 153 } 154 } 155 156 static void smbd_sig_hup_handler(struct tevent_context *ev, 157 struct tevent_signal *se, 158 int signum, 159 int count, 160 void *siginfo, 161 void *private_data) 162 { 163 struct messaging_context *msg_ctx = talloc_get_type_abort( 164 private_data, struct messaging_context); 165 change_to_root_user(); 166 DEBUG(1,("Reloading services after SIGHUP\n")); 167 reload_services(msg_ctx, smbd_server_conn->sock, false); 168 } 169 170 static void smbd_setup_sig_hup_handler(struct tevent_context *ev, 171 struct messaging_context *msg_ctx) 172 { 173 struct tevent_signal *se; 174 175 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler, 176 msg_ctx); 177 if (!se) { 178 exit_server("failed to setup SIGHUP handler"); 179 } 180 } 181 145 182 146 183 /******************************************************************* … … 784 821 smb_stat_cache_delete); 785 822 messaging_register(msg_ctx, NULL, MSG_DEBUG, smbd_msg_debug); 786 messaging_register(msg_ctx, server_event_context(), MSG_PRINTER_PCAP,787 smb_pcap_updated);788 823 brl_register_msgs(msg_ctx); 789 824 … … 909 944 NTSTATUS status; 910 945 911 #ifdef __OS2__912 EXCEPTIONREGISTRATIONRECORD ExRegRec;913 LoadExceptq(&ExRegRec, NULL, NULL);914 #endif915 946 /* 916 947 * Do this before any other talloc operation … … 1264 1295 exit(1); 1265 1296 1266 /* Publish nt printers, this requires a working winreg pipe */1267 pcap_cache_reload(server_event_context(), smbd_messaging_context(),1268 &reload_printers);1269 1270 1297 /* only start the background queue daemon if we are 1271 1298 running as a daemon -- bad things will happen if … … 1275 1302 if (is_daemon && !interactive 1276 1303 && lp_parm_bool(-1, "smbd", "backgroundqueue", true)) { 1277 start_background_queue(smbd_event_context(), 1278 smbd_messaging_context()); 1304 /* background queue is responsible for printcap cache updates */ 1305 messaging_register(smbd_server_conn->msg_ctx, 1306 smbd_event_context(), 1307 MSG_PRINTER_PCAP, smb_pcap_updated); 1308 start_background_queue(server_event_context(), 1309 smbd_server_conn->msg_ctx); 1310 } else { 1311 DEBUG(3, ("running without background printer process, dynamic " 1312 "printer updates disabled\n")); 1313 /* Publish nt printers, this requires a working winreg pipe */ 1314 pcap_cache_reload(server_event_context(), 1315 smbd_messaging_context(), 1316 &reload_printers_full); 1279 1317 } 1280 1318 … … 1335 1373 exit_server_cleanly(NULL); 1336 1374 TALLOC_FREE(frame); 1337 #ifdef __OS2__1338 UninstallExceptq(&ExRegRec);1339 #endif1340 1375 return(0); 1341 1376 } -
trunk/server/source3/smbd/server_reload.c
r751 r862 37 37 struct messaging_context *msg_ctx) 38 38 { 39 int n_services; 40 int pnum; 41 int snum; 42 const char *pname; 43 44 n_services = lp_numservices(); 45 pnum = lp_servicenumber(PRINTERS_NAME); 46 47 DEBUG(10, ("reloading printer services from pcap cache\n")); 48 49 /* 50 * Add default config for printers added to smb.conf file and remove 51 * stale printers 52 */ 53 for (snum = 0; snum < n_services; snum++) { 54 /* avoid removing PRINTERS_NAME */ 55 if (snum == pnum) { 56 continue; 57 } 58 59 /* skip no-printer services */ 60 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) { 61 continue; 62 } 63 64 pname = lp_printername(snum); 65 66 /* check printer, but avoid removing non-autoloaded printers */ 67 if (lp_autoloaded(snum) && !pcap_printername_ok(pname)) { 68 DEBUG(3, ("removing stale printer %s\n", pname)); 69 lp_killservice(snum); 70 } 71 } 72 73 /* Make sure deleted printers are gone */ 74 load_printers(ev, msg_ctx); 75 } 76 77 /**************************************************************************** 78 purge stale printers and reload from pre-populated pcap cache 79 **************************************************************************/ 80 void reload_printers_full(struct tevent_context *ev, 81 struct messaging_context *msg_ctx) 82 { 39 83 struct auth_serversupplied_info *session_info = NULL; 40 struct spoolss_PrinterInfo2 *pinfo2 = NULL;41 84 int n_services; 42 85 int pnum; … … 46 89 NTSTATUS status; 47 90 48 load_printers(ev, msg_ctx);49 50 91 n_services = lp_numservices(); 51 92 pnum = lp_servicenumber(PRINTERS_NAME); 52 93 53 DEBUG(10, ("reloading printer services from pcap cache\n")); 54 55 status = make_session_info_system(talloc_tos(), &session_info); 94 status = make_session_info_system(talloc_new(NULL), &session_info); 56 95 if (!NT_STATUS_IS_OK(status)) { 57 DEBUG(3, ("reload_printers: " 58 "Could not create system session_info\n")); 96 DEBUG(3, ("Could not create system session_info\n")); 59 97 /* can't remove stale printers before we 60 98 * are fully initilized */ … … 82 120 /* check printer, but avoid removing non-autoloaded printers */ 83 121 if (lp_autoloaded(snum) && !pcap_printername_ok(pname)) { 84 DEBUG(3, ("removing stale printer %s\n", pname)); 85 122 struct spoolss_PrinterInfo2 *pinfo2 = NULL; 86 123 if (is_printer_published(session_info, session_info, 87 124 msg_ctx, 88 NULL, lp_servicename(snum), 89 NULL, &pinfo2)) { 125 NULL, 126 lp_servicename(snum), 127 &pinfo2)) { 90 128 nt_printer_publish(session_info, 91 129 session_info, … … 97 135 nt_printer_remove(session_info, session_info, msg_ctx, 98 136 pname); 99 lp_killservice(snum);100 137 } else { 101 138 DEBUG(8, ("Adding default registry entry for printer " … … 106 143 } 107 144 108 /* Make sure deleted printers are gone*/109 load_printers(ev, msg_ctx);145 /* finally, purge old snums */ 146 reload_printers(ev, msg_ctx); 110 147 111 148 TALLOC_FREE(session_info); … … 161 198 return(ret); 162 199 } 163 164 /****************************************************************************165 Notify smbds of new printcap data166 **************************************************************************/167 void reload_pcap_change_notify(struct tevent_context *ev,168 struct messaging_context *msg_ctx)169 {170 /*171 * Reload the printers first in the background process so that172 * newly added printers get default values created in the registry.173 *174 * This will block the process for some time (~1 sec per printer), but175 * it doesn't block smbd's servering clients.176 */177 reload_printers(ev, msg_ctx);178 179 message_send_all(msg_ctx, MSG_PRINTER_PCAP, NULL, 0, NULL);180 } -
trunk/server/source3/smbd/service.c
r751 r862 162 162 /* Assume OS/2 users are smart enough to put a correct path in smb.conf, and simply copy the string */ 163 163 safe_strcpy(destname, connectpath, strlen(connectpath)); 164 #endif 164 #endif 165 165 166 166 DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n", … … 662 662 } 663 663 664 return make_serverinfo_from_username(mem_ctx, user, guest, 664 return make_serverinfo_from_username(mem_ctx, user, guest, guest, 665 665 presult); 666 666 } … … 696 696 697 697 status = make_serverinfo_from_username( 698 conn, fuser, conn->session_info->guest,698 conn, fuser, false, conn->session_info->guest, 699 699 &forced_serverinfo); 700 700 if (!NT_STATUS_IS_OK(status)) { -
trunk/server/source3/smbd/sesssetup.c
r751 r862 910 910 (unsigned int)pblob->length )); 911 911 912 if (pblob->length > pad->needed_len) { 913 DEBUG(2, ("subsequent security token data length %u " 914 "exceeds expected length %u\n", 915 (unsigned int)pblob->length, 916 (unsigned int)pad->needed_len)); 917 } 918 912 919 tmp_blob = data_blob(NULL, 913 920 pad->partial_data.length + copy_len); … … 1170 1177 status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1); 1171 1178 if (!NT_STATUS_IS_OK(status)) { 1179 /* 1180 * Pack error response, ensuring to fill NativeOS, NativeLanMan 1181 * & PrimaryDomain fields on NT_STATUS_MORE_PROCESSING_REQUIRED 1182 */ 1183 reply_outbuf(req, 4, 0); 1184 reply_sesssetup_blob(req, data_blob_null, status); 1172 1185 if (!NT_STATUS_EQUAL(status, 1173 1186 NT_STATUS_MORE_PROCESSING_REQUIRED)) { … … 1176 1189 } 1177 1190 data_blob_free(&blob1); 1178 reply_nterror(req, nt_status_squash(status));1179 1191 return; 1180 1192 } -
trunk/server/source3/smbd/smb2_create.c
r751 r862 695 695 smb1req->flags2 & FLAGS2_DFS_PATHNAMES, 696 696 fname, 697 0, 697 (in_create_disposition == FILE_CREATE) ? 698 UCF_CREATING_FILE : 0, 698 699 NULL, 699 700 &smb_fname); … … 894 895 return false; 895 896 } 896 if (!smb2req->async) {897 return false;898 }899 897 req = smb2req->subreq; 900 898 if (!req) { … … 903 901 state = tevent_req_data(req, struct smbd_smb2_create_state); 904 902 if (!state) { 903 return false; 904 } 905 if (!state->open_was_deferred) { 905 906 return false; 906 907 } -
trunk/server/source3/smbd/smb2_getinfo.c
r751 r862 149 149 } 150 150 151 if (!NT_STATUS_IS_OK(call_status)) { 151 /* some GetInfo responses set STATUS_BUFFER_OVERFLOW and return partial, 152 but valid data */ 153 if (!(NT_STATUS_IS_OK(call_status) || 154 NT_STATUS_EQUAL(call_status, STATUS_BUFFER_OVERFLOW))) { 152 155 /* Return a specific error with data. */ 153 156 error = smbd_smb2_request_error_ex(req, … … 186 189 outdyn = out_output_buffer; 187 190 188 error = smbd_smb2_request_done (req, outbody, &outdyn);191 error = smbd_smb2_request_done_ex(req, call_status, outbody, &outdyn, __location__); 189 192 if (!NT_STATUS_IS_OK(error)) { 190 193 smbd_server_connection_terminate(req->sconn, … … 271 274 272 275 switch (in_info_type) { 273 case 0x01:/* SMB2_GETINFO_FILE */276 case SMB2_GETINFO_FILE: 274 277 { 275 278 uint16_t file_info_level; … … 282 285 int lock_data_count = 0; 283 286 char *lock_data = NULL; 287 size_t fixed_portion; 284 288 285 289 ZERO_STRUCT(write_time_ts); … … 369 373 STR_UNICODE, 370 374 in_output_buffer_length, 375 &fixed_portion, 371 376 &data, 372 377 &data_size); … … 377 382 } 378 383 tevent_req_nterror(req, status); 384 return tevent_req_post(req, ev); 385 } 386 if (in_output_buffer_length < fixed_portion) { 387 SAFE_FREE(data); 388 tevent_req_nterror( 389 req, NT_STATUS_INFO_LENGTH_MISMATCH); 379 390 return tevent_req_post(req, ev); 380 391 } … … 387 398 return tevent_req_post(req, ev); 388 399 } 400 if (data_size > in_output_buffer_length) { 401 state->out_output_buffer.length = 402 in_output_buffer_length; 403 status = STATUS_BUFFER_OVERFLOW; 404 } 389 405 } 390 406 SAFE_FREE(data); … … 392 408 } 393 409 394 case 0x02:/* SMB2_GETINFO_FS */410 case SMB2_GETINFO_FS: 395 411 { 396 412 uint16_t file_info_level; 397 413 char *data = NULL; 398 414 int data_size = 0; 415 size_t fixed_portion; 399 416 400 417 /* the levels directly map to the passthru levels */ … … 405 422 STR_UNICODE, 406 423 in_output_buffer_length, 424 &fixed_portion, 425 fsp->fsp_name, 407 426 &data, 408 427 &data_size); 409 if (!NT_STATUS_IS_OK(status)) { 428 /* some responses set STATUS_BUFFER_OVERFLOW and return 429 partial, but valid data */ 430 if (!(NT_STATUS_IS_OK(status) || 431 NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW))) { 410 432 SAFE_FREE(data); 411 433 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) { … … 413 435 } 414 436 tevent_req_nterror(req, status); 437 return tevent_req_post(req, ev); 438 } 439 if (in_output_buffer_length < fixed_portion) { 440 SAFE_FREE(data); 441 tevent_req_nterror( 442 req, NT_STATUS_INFO_LENGTH_MISMATCH); 415 443 return tevent_req_post(req, ev); 416 444 } … … 423 451 return tevent_req_post(req, ev); 424 452 } 453 if (data_size > in_output_buffer_length) { 454 state->out_output_buffer.length = 455 in_output_buffer_length; 456 status = STATUS_BUFFER_OVERFLOW; 457 } 425 458 } 426 459 SAFE_FREE(data); … … 428 461 } 429 462 430 case 0x03:/* SMB2_GETINFO_SEC */463 case SMB2_GETINFO_SECURITY: 431 464 { 432 465 uint8_t *p_marshalled_sd = NULL; … … 485 518 } 486 519 520 state->status = status; 487 521 tevent_req_done(req); 488 522 return tevent_req_post(req, ev); -
trunk/server/source3/smbd/smb2_server.c
r751 r862 928 928 uint64_t message_id = 0; 929 929 uint64_t async_id = 0; 930 struct iovec *outvec = NULL;931 930 932 931 if (!tevent_req_is_in_progress(subreq)) { … … 945 944 /* 946 945 * We're trying to go async in a compound 947 * request chain. This is not allowed. 948 * Cancel the outstanding request. 949 */ 950 bool ok = tevent_req_cancel(req->subreq); 951 if (ok) { 952 return NT_STATUS_OK; 953 } 954 TALLOC_FREE(req->subreq); 955 return smbd_smb2_request_error(req, 956 NT_STATUS_INTERNAL_ERROR); 946 * request chain. 947 * This is only allowed for opens that 948 * cause an oplock break, otherwise it 949 * is not allowed. See [MS-SMB2].pdf 950 * note <194> on Section 3.3.5.2.7. 951 */ 952 const uint8_t *inhdr = 953 (const uint8_t *)req->in.vector[i].iov_base; 954 955 if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_CREATE) { 956 /* 957 * Cancel the outstanding request. 958 */ 959 bool ok = tevent_req_cancel(req->subreq); 960 if (ok) { 961 return NT_STATUS_OK; 962 } 963 TALLOC_FREE(req->subreq); 964 return smbd_smb2_request_error(req, 965 NT_STATUS_INTERNAL_ERROR); 966 } 957 967 } 958 968 … … 963 973 } 964 974 965 if (req->out.vector_count > 4) { 966 /* This is a compound reply. We 967 * must do an interim response 968 * followed by the async response 969 * to match W2K8R2. 975 if (i > 1) { 976 /* 977 * We're going async in a compound 978 * chain after the first request has 979 * already been processed. Send an 980 * interim response containing the 981 * set of replies already generated. 970 982 */ 971 983 status = smb2_send_async_interim_response(req); … … 974 986 } 975 987 976 /* 977 * We're splitting off the last SMB2 978 * request in a compound set, and the 979 * smb2_send_async_interim_response() 980 * call above just sent all the replies 981 * for the previous SMB2 requests in 982 * this compound set. So we're no longer 983 * in the "compound_related_in_progress" 984 * state, and this is no longer a compound 985 * request. 986 */ 987 req->compound_related = false; 988 req->sconn->smb2.compound_related_in_progress = false; 988 req->current_idx = 1; 989 990 /* 991 * Re-arrange the in.vectors to remove what 992 * we just sent. 993 */ 994 memmove(&req->in.vector[1], 995 &req->in.vector[i], 996 sizeof(req->in.vector[0])*(req->in.vector_count - i)); 997 req->in.vector_count = 1 + (req->in.vector_count - i); 998 999 smb2_setup_nbt_length(req->in.vector, req->in.vector_count); 1000 1001 /* Re-arrange the out.vectors to match. */ 1002 memmove(&req->out.vector[1], 1003 &req->out.vector[i], 1004 sizeof(req->out.vector[0])*(req->out.vector_count - i)); 1005 req->out.vector_count = 1 + (req->out.vector_count - i); 1006 1007 if (req->in.vector_count == 4) { 1008 uint8_t *outhdr = (uint8_t *)req->out.vector[i].iov_base; 1009 /* 1010 * We only have one remaining request as 1011 * we've processed everything else. 1012 * This is no longer a compound request. 1013 */ 1014 req->compound_related = false; 1015 flags = (IVAL(outhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED); 1016 SIVAL(outhdr, SMB2_HDR_FLAGS, flags); 1017 } 989 1018 } 990 1019 991 1020 /* Don't return an intermediate packet on a pipe read/write. */ 992 1021 if (req->tcon && req->tcon->compat_conn && IS_IPC(req->tcon->compat_conn)) { 993 goto ipc_out;1022 goto out; 994 1023 } 995 1024 … … 1081 1110 /* Note we're going async with this request. */ 1082 1111 req->async = true; 1083 1084 ipc_out:1085 1086 /*1087 * Now manipulate req so that the outstanding async request1088 * is the only one left in the struct smbd_smb2_request.1089 */1090 1091 if (req->current_idx == 1) {1092 /* There was only one. */1093 goto out;1094 }1095 1096 /* Re-arrange the in.vectors. */1097 req->in.vector[1] = req->in.vector[i];1098 req->in.vector[2] = req->in.vector[i+1];1099 req->in.vector[3] = req->in.vector[i+2];1100 req->in.vector_count = 4;1101 /* Reset the new in size. */1102 smb2_setup_nbt_length(req->in.vector, 4);1103 1104 /* Now recreate the out.vectors. */1105 outvec = talloc_zero_array(req, struct iovec, 4);1106 if (!outvec) {1107 return NT_STATUS_NO_MEMORY;1108 }1109 1110 /* 0 is always boilerplate and must1111 * be of size 4 for the length field. */1112 1113 outvec[0].iov_base = req->out.nbt_hdr;1114 outvec[0].iov_len = 4;1115 SIVAL(req->out.nbt_hdr, 0, 0);1116 1117 if (!dup_smb2_vec3(outvec, &outvec[1], &req->out.vector[i])) {1118 return NT_STATUS_NO_MEMORY;1119 }1120 1121 TALLOC_FREE(req->out.vector);1122 1123 req->out.vector = outvec;1124 1125 req->current_idx = 1;1126 req->out.vector_count = 4;1127 1112 1128 1113 out: … … 1178 1163 uint64_t message_id; 1179 1164 uint64_t async_id; 1165 1166 if (cur->compound_related) { 1167 /* 1168 * Never cancel anything in a compound request. 1169 * Way too hard to deal with the result. 1170 */ 1171 continue; 1172 } 1180 1173 1181 1174 i = cur->current_idx; … … 1361 1354 if (flags & SMB2_HDR_FLAG_CHAINED) { 1362 1355 req->compound_related = true; 1363 req->sconn->smb2.compound_related_in_progress = true;1364 1356 } 1365 1357 … … 1803 1795 return NT_STATUS_NO_MEMORY; 1804 1796 } 1797 1798 if (req->do_signing) { 1799 /* 1800 * We sign each reply as we go along. 1801 * We can do this as smb2_calculate_credits() 1802 * grants zero credits on every part of a 1803 * compound reply except the last one, 1804 * which is signed just before calling 1805 * tstream_writev_queue_send(). 1806 */ 1807 NTSTATUS status; 1808 status = smb2_signing_sign_pdu(req->session->session_key, 1809 &req->out.vector[i], 3); 1810 if (!NT_STATUS_IS_OK(status)) { 1811 TALLOC_FREE(im); 1812 return status; 1813 } 1814 } 1815 1805 1816 tevent_schedule_immediate(im, 1806 1817 req->sconn->smb2.event_ctx, … … 1812 1823 if (req->compound_related) { 1813 1824 req->compound_related = false; 1814 req->sconn->smb2.compound_related_in_progress = false;1815 1825 } 1816 1826 … … 2529 2539 struct tevent_req *subreq; 2530 2540 2531 if (sconn->smb2.compound_related_in_progress) {2532 /*2533 * Can't read another until the related2534 * compound is done.2535 */2536 return NT_STATUS_OK;2537 }2538 2539 2541 if (tevent_queue_length(sconn->smb2.recv_queue) > 0) { 2540 2542 /* -
trunk/server/source3/smbd/smb2_tcon.c
r751 r862 208 208 } 209 209 210 /* Don't allow connection if encryption is required. */ 211 if (lp_smb_encrypt(snum) == Required) { 212 DEBUG(0,("Connection refused on share %s as encryption is" 213 " required on this share and SMB2 does not support" 214 " this.\n", 215 lp_servicename(snum))); 216 return NT_STATUS_ACCESS_DENIED; 217 } 218 210 219 /* create a new tcon as child of the session */ 211 220 tcon = talloc_zero(req->session, struct smbd_smb2_tcon); -
trunk/server/source3/smbd/trans2.c
r792 r862 25 25 26 26 #include "includes.h" 27 #include "ntioctl.h" 27 28 #include "system/filesys.h" 28 29 #include "version.h" … … 337 338 } 338 339 340 if (listp->ea.value.length == 0) { 341 /* 342 * We can never return a zero length EA. 343 * Windows reports the EA's as corrupted. 344 */ 345 TALLOC_FREE(listp); 346 continue; 347 } 348 339 349 push_ascii_fstring(dos_ea_name, listp->ea.name); 340 350 … … 420 430 uint8_t *p = (uint8_t *)pdata; 421 431 uint8_t *last_start = NULL; 432 bool store_data = (pdata != NULL); 422 433 423 434 *ret_data_size = 0; … … 431 442 fstring dos_ea_name; 432 443 size_t this_size; 433 434 if (last_start) { 444 size_t pad = 0; 445 446 if (last_start && store_data) { 435 447 SIVAL(last_start, 0, PTR_DIFF(p, last_start)); 436 448 } … … 449 461 450 462 if (ea_list->next) { 451 size_t pad = 4 - (this_size % 4);463 pad = (4 - (this_size % 4)) % 4; 452 464 this_size += pad; 453 465 } … … 458 470 459 471 /* We know we have room. */ 460 SIVAL(p, 0x00, 0); /* next offset */ 461 SCVAL(p, 0x04, ea_list->ea.flags); 462 SCVAL(p, 0x05, dos_namelen); 463 SSVAL(p, 0x06, ea_list->ea.value.length); 464 fstrcpy((char *)(p+0x08), dos_ea_name); 465 memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length); 472 if (store_data) { 473 SIVAL(p, 0x00, 0); /* next offset */ 474 SCVAL(p, 0x04, ea_list->ea.flags); 475 SCVAL(p, 0x05, dos_namelen); 476 SSVAL(p, 0x06, ea_list->ea.value.length); 477 fstrcpy((char *)(p+0x08), dos_ea_name); 478 memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length); 479 if (pad) { 480 memset(p + 0x08 + dos_namelen + 1 + ea_list->ea.value.length, 481 '\0', 482 pad); 483 } 484 } 466 485 467 486 total_data_size -= this_size; … … 477 496 { 478 497 size_t total_ea_len = 0; 498 struct ea_list *ea_list = NULL; 479 499 TALLOC_CTX *mem_ctx = NULL; 480 500 … … 483 503 } 484 504 mem_ctx = talloc_tos(); 485 (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); 505 ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); 506 if (ea_list == NULL) { 507 return 0; 508 } 509 if(conn->sconn->using_smb2) { 510 NTSTATUS status; 511 unsigned int ret_data_size; 512 /* 513 * We're going to be using fill_ea_chained_buffer() to 514 * marshall EA's - this size is significantly larger 515 * than the SMB1 buffer. Re-calculate the size without 516 * marshalling. 517 */ 518 status = fill_ea_chained_buffer(mem_ctx, 519 NULL, 520 65535, 521 &ret_data_size, 522 conn, 523 ea_list); 524 if (!NT_STATUS_IS_OK(status)) { 525 ret_data_size = 0; 526 } 527 total_ea_len = ret_data_size; 528 } 529 486 530 return total_ea_len; 487 531 } … … 1744 1788 SIVAL(p,0,mode); p += 4; 1745 1789 q = p; p += 4; /* q is placeholder for name length. */ 1746 { 1790 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) { 1791 SIVAL(p, 0, IO_REPARSE_TAG_DFS); 1792 } else { 1747 1793 unsigned int ea_size = estimate_ea_size(conn, NULL, 1748 1794 smb_fname->base_name); 1749 1795 SIVAL(p,0,ea_size); /* Extended attributes */ 1750 p += 4;1751 }1796 } 1797 p += 4; 1752 1798 /* Clear the short name buffer. This is 1753 1799 * IMPORTANT as not doing so will trigger … … 1921 1967 SIVAL(p,0,mode); p += 4; 1922 1968 q = p; p += 4; /* q is placeholder for name length. */ 1923 { 1969 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) { 1970 SIVAL(p, 0, IO_REPARSE_TAG_DFS); 1971 } else { 1924 1972 unsigned int ea_size = estimate_ea_size(conn, NULL, 1925 1973 smb_fname->base_name); 1926 1974 SIVAL(p,0,ea_size); /* Extended attributes */ 1927 p +=4;1928 }1975 } 1976 p +=4; 1929 1977 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */ 1930 1978 SBVAL(p,0,file_index); p += 8; … … 1967 2015 SIVAL(p,0,mode); p += 4; 1968 2016 q = p; p += 4; /* q is placeholder for name length */ 1969 { 2017 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) { 2018 SIVAL(p, 0, IO_REPARSE_TAG_DFS); 2019 } else { 1970 2020 unsigned int ea_size = estimate_ea_size(conn, NULL, 1971 2021 smb_fname->base_name); 1972 2022 SIVAL(p,0,ea_size); /* Extended attributes */ 1973 p +=4;1974 }2023 } 2024 p +=4; 1975 2025 /* Clear the short name buffer. This is 1976 2026 * IMPORTANT as not doing so will trigger … … 2935 2985 uint16_t flags2, 2936 2986 unsigned int max_data_bytes, 2987 size_t *fixed_portion, 2988 struct smb_filename *fname, 2937 2989 char **ppdata, 2938 2990 int *ret_data_len) … … 2943 2995 int snum = SNUM(conn); 2944 2996 char *fstype = lp_fstype(SNUM(conn)); 2997 const char *filename = NULL; 2945 2998 uint32 additional_flags = 0; 2946 struct smb_filename smb_fname _dot;2999 struct smb_filename smb_fname; 2947 3000 SMB_STRUCT_STAT st; 3001 NTSTATUS status = NT_STATUS_OK; 3002 3003 if (fname == NULL || fname->base_name == NULL) { 3004 filename = "."; 3005 } else { 3006 filename = fname->base_name; 3007 } 2948 3008 2949 3009 if (IS_IPC(conn)) { … … 2958 3018 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level)); 2959 3019 2960 ZERO_STRUCT(smb_fname _dot);2961 smb_fname _dot.base_name = discard_const_p(char, ".");2962 2963 if(SMB_VFS_STAT(conn, &smb_fname _dot) != 0) {3020 ZERO_STRUCT(smb_fname); 3021 smb_fname.base_name = discard_const_p(char, filename); 3022 3023 if(SMB_VFS_STAT(conn, &smb_fname) != 0) { 2964 3024 DEBUG(2,("stat of . failed (%s)\n", strerror(errno))); 2965 3025 return map_nt_error_from_unix(errno); 2966 3026 } 2967 3027 2968 st = smb_fname _dot.st;3028 st = smb_fname.st; 2969 3029 2970 3030 *ppdata = (char *)SMB_REALLOC( … … 2977 3037 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 2978 3038 end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1; 3039 3040 *fixed_portion = 0; 2979 3041 2980 3042 switch (info_level) { … … 2983 3045 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 2984 3046 data_len = 18; 2985 if (get_dfree_info(conn, ".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {3047 if (get_dfree_info(conn,filename,False,&bsize,&dfree,&dsize) == (uint64_t)-1) { 2986 3048 return map_nt_error_from_unix(errno); 2987 3049 } … … 3070 3132 SIVAL(pdata,8,len); 3071 3133 data_len = 12 + len; 3134 if (max_data_bytes >= 16 && data_len > max_data_bytes) { 3135 /* the client only requested a portion of the 3136 file system name */ 3137 data_len = max_data_bytes; 3138 status = STATUS_BUFFER_OVERFLOW; 3139 } 3140 *fixed_portion = 16; 3072 3141 break; 3073 3142 … … 3099 3168 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", 3100 3169 (int)strlen(vname),vname, lp_servicename(snum))); 3170 if (max_data_bytes >= 24 && data_len > max_data_bytes) { 3171 /* the client only requested a portion of the 3172 volume label */ 3173 data_len = max_data_bytes; 3174 status = STATUS_BUFFER_OVERFLOW; 3175 } 3176 3101 3177 break; 3102 3178 … … 3106 3182 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 3107 3183 data_len = 24; 3108 if (get_dfree_info(conn, ".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {3184 if (get_dfree_info(conn,filename,False,&bsize,&dfree,&dsize) == (uint64_t)-1) { 3109 3185 return map_nt_error_from_unix(errno); 3110 3186 } … … 3131 3207 SIVAL(pdata,16,sectors_per_unit); 3132 3208 SIVAL(pdata,20,bytes_per_sector); 3209 *fixed_portion = 24; 3133 3210 break; 3134 3211 } … … 3138 3215 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 3139 3216 data_len = 32; 3140 if (get_dfree_info(conn, ".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {3217 if (get_dfree_info(conn,filename,False,&bsize,&dfree,&dsize) == (uint64_t)-1) { 3141 3218 return map_nt_error_from_unix(errno); 3142 3219 } … … 3164 3241 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */ 3165 3242 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */ 3243 *fixed_portion = 32; 3166 3244 break; 3167 3245 } … … 3178 3256 SIVAL(pdata,0,FILE_DEVICE_DISK); /* dev type */ 3179 3257 SIVAL(pdata,4,characteristics); 3258 *fixed_portion = 8; 3180 3259 break; 3181 3260 } … … 3331 3410 } 3332 3411 3333 rc = SMB_VFS_STATVFS(conn, ".", &svfs);3412 rc = SMB_VFS_STATVFS(conn, filename, &svfs); 3334 3413 3335 3414 if (!rc) { … … 3352 3431 return NT_STATUS_DOS(ERRSRV, ERRerror); 3353 3432 } 3433 *fixed_portion = 24; 3354 3434 break; 3355 3435 } … … 3482 3562 3483 3563 *ret_data_len = data_len; 3484 return NT_STATUS_OK;3564 return status; 3485 3565 } 3486 3566 … … 3498 3578 uint16_t info_level; 3499 3579 int data_len = 0; 3580 size_t fixed_portion; 3500 3581 NTSTATUS status; 3501 3582 … … 3524 3605 req->flags2, 3525 3606 max_data_bytes, 3607 &fixed_portion, 3608 NULL, 3526 3609 ppdata, &data_len); 3527 3610 if (!NT_STATUS_IS_OK(status)) { … … 4076 4159 unsigned int ofs = 0; 4077 4160 4078 for (i = 0; i < num_streams && ofs <= max_data_bytes; i++) { 4161 if (max_data_bytes < 32) { 4162 return NT_STATUS_INFO_LENGTH_MISMATCH; 4163 } 4164 4165 for (i = 0; i < num_streams; i++) { 4079 4166 unsigned int next_offset; 4080 4167 size_t namelen; … … 4095 4182 namelen -= 2; 4096 4183 4184 /* 4185 * We cannot overflow ... 4186 */ 4187 if ((ofs + 24 + namelen) > max_data_bytes) { 4188 DEBUG(10, ("refusing to overflow reply at stream %u\n", 4189 i)); 4190 TALLOC_FREE(namebuf); 4191 return STATUS_BUFFER_OVERFLOW; 4192 } 4193 4097 4194 SIVAL(data, ofs+4, namelen); 4098 4195 SOFF_T(data, ofs+8, streams[i].size); … … 4109 4206 unsigned int align = ndr_align_size(next_offset, 8); 4110 4207 4208 if ((next_offset + align) > max_data_bytes) { 4209 DEBUG(10, ("refusing to overflow align " 4210 "reply at stream %u\n", 4211 i)); 4212 TALLOC_FREE(namebuf); 4213 return STATUS_BUFFER_OVERFLOW; 4214 } 4215 4111 4216 memset(data+next_offset, 0, align); 4112 4217 next_offset += align; … … 4118 4223 ofs = next_offset; 4119 4224 } 4225 4226 DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes, ofs)); 4120 4227 4121 4228 *data_size = ofs; … … 4207 4314 uint16_t flags2, 4208 4315 unsigned int max_data_bytes, 4316 size_t *fixed_portion, 4209 4317 char **ppdata, 4210 4318 unsigned int *pdata_size) … … 4342 4450 file_index = get_FileIndex(conn, psbuf); 4343 4451 4452 *fixed_portion = 0; 4453 4344 4454 switch (info_level) { 4345 4455 case SMB_INFO_STANDARD: … … 4479 4589 DEBUG(5,("change: %s ", ctime(&c_time))); 4480 4590 DEBUG(5,("mode: %x\n", mode)); 4591 *fixed_portion = data_size; 4481 4592 break; 4482 4593 … … 4492 4603 SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0); 4493 4604 SSVAL(pdata,22,0); /* Padding. */ 4605 *fixed_portion = 24; 4494 4606 break; 4495 4607 … … 4501 4613 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); 4502 4614 data_size = 4; 4615 *fixed_portion = 4; 4503 4616 SIVAL(pdata,0,ea_size); 4504 4617 break; … … 4522 4635 data_size = 4 + len; 4523 4636 SIVAL(pdata,0,len); 4637 *fixed_portion = 8; 4524 4638 break; 4525 4639 } … … 4585 4699 pdata += 4 + len; 4586 4700 data_size = PTR_DIFF(pdata,(*ppdata)); 4701 *fixed_portion = 10; 4587 4702 break; 4588 4703 } … … 4622 4737 pdata += 4 + len; 4623 4738 data_size = PTR_DIFF(pdata,(*ppdata)); 4739 *fixed_portion = 104; 4624 4740 break; 4625 4741 } … … 4629 4745 SBVAL(pdata, 0, file_index); 4630 4746 data_size = 8; 4747 *fixed_portion = 8; 4631 4748 break; 4632 4749 … … 4635 4752 SIVAL(pdata, 0, access_mask); 4636 4753 data_size = 4; 4754 *fixed_portion = 4; 4637 4755 break; 4638 4756 … … 4652 4770 data_size = 1; 4653 4771 SCVAL(pdata,0,delete_pending); 4772 *fixed_portion = 1; 4654 4773 break; 4655 4774 … … 4658 4777 data_size = 8; 4659 4778 SOFF_T(pdata,0,pos); 4779 *fixed_portion = 8; 4660 4780 break; 4661 4781 … … 4664 4784 SIVAL(pdata,0,mode); 4665 4785 data_size = 4; 4786 *fixed_portion = 4; 4666 4787 break; 4667 4788 … … 4670 4791 SIVAL(pdata,0,0); /* No alignment needed. */ 4671 4792 data_size = 4; 4793 *fixed_portion = 4; 4672 4794 break; 4673 4795 … … 4708 4830 DEBUG(10, ("marshall_stream_info failed: %s\n", 4709 4831 nt_errstr(status))); 4832 TALLOC_FREE(streams); 4710 4833 return status; 4711 4834 } 4712 4835 4713 4836 TALLOC_FREE(streams); 4837 4838 *fixed_portion = 32; 4714 4839 4715 4840 break; … … 4722 4847 SIVAL(pdata,12,0); /* ??? */ 4723 4848 data_size = 16; 4849 *fixed_portion = 16; 4724 4850 break; 4725 4851 … … 4735 4861 SIVAL(pdata,52,0); /* ??? */ 4736 4862 data_size = 56; 4863 *fixed_portion = 56; 4737 4864 break; 4738 4865 … … 4742 4869 SIVAL(pdata,4,0); 4743 4870 data_size = 8; 4871 *fixed_portion = 8; 4744 4872 break; 4745 4873 … … 5011 5139 int lock_data_count = 0; 5012 5140 char *lock_data = NULL; 5141 size_t fixed_portion; 5013 5142 NTSTATUS status = NT_STATUS_OK; 5014 5143 … … 5372 5501 lock_data_count, lock_data, 5373 5502 req->flags2, max_data_bytes, 5503 &fixed_portion, 5374 5504 ppdata, &data_size); 5375 5505 if (!NT_STATUS_IS_OK(status)) { 5376 5506 reply_nterror(req, status); 5507 return; 5508 } 5509 if (fixed_portion > max_data_bytes) { 5510 reply_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH); 5377 5511 return; 5378 5512 } … … 7325 7459 create_disp = FILE_OPEN_IF; 7326 7460 break; 7461 case SMB_O_EXCL: 7462 /* O_EXCL on its own without O_CREAT is undefined. 7463 We deliberately ignore it as some versions of 7464 Linux CIFSFS can send a bare O_EXCL on the 7465 wire which other filesystems in the kernel 7466 ignore. See bug 9519 for details. */ 7467 7468 /* Fallthrough. */ 7469 7327 7470 case 0: 7328 7471 /* File exists open. File not exist fail. */ 7329 7472 create_disp = FILE_OPEN; 7330 7473 break; 7331 case SMB_O_EXCL:7332 /* O_EXCL on its own without O_CREAT is undefined. */7333 7474 default: 7334 7475 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n", … … 7583 7724 } 7584 7725 /* Fail with sharing violation. */ 7726 TALLOC_FREE(lck); 7585 7727 close_file(req, fsp, NORMAL_CLOSE); 7586 TALLOC_FREE(lck);7587 7728 return NT_STATUS_SHARING_VIOLATION; 7588 7729 } … … 7598 7739 smb_fname); 7599 7740 7741 TALLOC_FREE(lck); 7742 7600 7743 if (!NT_STATUS_IS_OK(status)) { 7601 7744 close_file(req, fsp, NORMAL_CLOSE); 7602 TALLOC_FREE(lck);7603 7745 return status; 7604 7746 } 7605 TALLOC_FREE(lck);7606 7747 return close_file(req, fsp, NORMAL_CLOSE); 7607 7748 }
Note:
See TracChangeset
for help on using the changeset viewer.