Ignore:
Timestamp:
May 13, 2014, 11:39:04 AM (11 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update trunk to 3.6.23

Location:
trunk/server
Files:
25 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/smbd/conn.c

    r751 r862  
    482482                DEBUG(1,("Forcing close of all shares\n"));
    483483                conn_close_all(sconn);
    484                 return;
     484                goto done;
    485485        }
    486486
     
    513513                }
    514514        }
    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  
    5050        unsigned int name_cache_index;
    5151        unsigned int file_number;
     52        files_struct *fsp; /* Back pointer to containing fsp, only
     53                              set from OpenDir_fsp(). */
    5254};
    5355
     
    591593{
    592594        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                 */
    605600                dptr_close_internal(fsp->dptr);
    606601                fsp->dptr = NULL;
     
    942937{
    943938        connection_struct *conn = dirptr->conn;
    944         bool needslash;
     939        size_t slashlen;
     940        size_t pathlen;
    945941
    946942        *_smb_fname = NULL;
    947943        *_mode = 0;
    948944
    949         needslash = ( dirptr->path[strlen(dirptr->path) -1] != '/');
     945        pathlen = strlen(dirptr->path);
     946        slashlen = ( dirptr->path[pathlen-1] != '/') ? 1 : 0;
    950947
    951948        while (true) {
     
    991988                }
    992989
    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));
    9971000                if (!pathreal) {
    9981001                        TALLOC_FREE(dname);
     
    10001003                        return false;
    10011004                }
     1005
     1006                memcpy(pathreal, dirptr->path, pathlen);
     1007                pathreal[pathlen] = '/';
     1008                memcpy(pathreal + slashlen + pathlen, dname,
     1009                       talloc_get_size(dname));
    10021010
    10031011                /* Create smb_fname with NULL stream_name. */
     
    13331341static int smb_Dir_destructor(struct smb_Dir *dirp)
    13341342{
    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;
    13431355                        }
    1344                 }
    1345 #endif
    1346                 SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir);
     1356                        dirp->fsp = NULL;
     1357                }
    13471358        }
    13481359        if (dirp->conn->sconn && !dirp->conn->sconn->using_smb2) {
     
    14281439        if (fsp->is_directory && fsp->fh->fd != -1) {
    14291440                dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr);
    1430                 if (dirp->dir == NULL) {
     1441                if (dirp->dir != NULL) {
     1442                        dirp->fsp = fsp;
     1443                } else {
    14311444                        DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned "
    14321445                                "NULL (%s)\n",
     
    16441657*****************************************************************/
    16451658
    1646 NTSTATUS can_delete_directory(struct connection_struct *conn,
    1647                                 const char *dirname)
     1659NTSTATUS can_delete_directory_fsp(files_struct *fsp)
    16481660{
    16491661        NTSTATUS status = NT_STATUS_OK;
     
    16521664        char *talloced = NULL;
    16531665        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);
    16561672
    16571673        if (!dir_hnd) {
     
    16681684                }
    16691685
    1670                 if (!is_visible_file(conn, dirname, dname, &st, True)) {
     1686                if (!is_visible_file(conn, fsp->fsp_name->base_name, dname, &st, True)) {
    16711687                        TALLOC_FREE(talloced);
    16721688                        continue;
    16731689                }
    16741690
    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",
    16761692                         dname ));
    16771693                status = NT_STATUS_DIRECTORY_NOT_EMPTY;
  • trunk/server/source3/smbd/dosmode.c

    r745 r862  
    504504        result = filter_mode_by_protocol(result);
    505505
     506        /*
     507         * Add in that it is a reparse point
     508         */
     509        result |= FILE_ATTRIBUTE_REPARSE_POINT;
     510
    506511        DEBUG(8,("dos_mode_msdfs returning "));
    507512
  • trunk/server/source3/smbd/filename.c

    r751 r862  
    446446                if (errno == ENOENT) {
    447447                        /* 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;
    449452                        status = check_parent_exists(ctx,
    450453                                                conn,
     
    453456                                                &dirpath,
    454457                                                &start);
     458                        errno = saved_errno;
    455459                        if (!NT_STATUS_IS_OK(status)) {
    456460                                goto fail;
     
    525529                 * is in the last component and the client already
    526530                 * sent the correct case.
     531                 * NOTE : check_parent_exists() doesn't preserve errno.
    527532                 */
     533                int saved_errno = errno;
    528534                status = check_parent_exists(ctx,
    529535                                        conn,
     
    532538                                        &dirpath,
    533539                                        &start);
     540                errno = saved_errno;
    534541                if (!NT_STATUS_IS_OK(status)) {
    535542                        goto fail;
     
    707714                                /*
    708715                                 * 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.
    712717                                 */
    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)) {
    715739                                        /*
    716740                                         * ENOTDIR and ELOOP both map to
  • trunk/server/source3/smbd/globals.h

    r751 r862  
    163163                               uint16_t flags2,
    164164                               unsigned int max_data_bytes,
     165                               size_t *fixed_portion,
    165166                               char **ppdata,
    166167                               unsigned int *pdata_size);
     
    180181                         uint16_t flags2,
    181182                         unsigned int max_data_bytes,
     183                         size_t *fixed_portion,
     184                         struct smb_filename *smb_fname,
    182185                         char **ppdata,
    183186                         int *ret_data_len);
     
    647650                uint32_t max_read;
    648651                uint32_t max_write;
    649                 bool compound_related_in_progress;
    650652        } smb2;
    651653};
  • trunk/server/source3/smbd/lanman.c

    r751 r862  
    26292629                goto close_domain;
    26302630        }
     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        }
    26312639
    26322640        if (type.ids[0] != SID_NAME_USER) {
     
    29372945
    29382946        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 checking
    2997          * 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);
    31922947}
    31932948
     
    57855540        {"NetServerEnum3",      RAP_NetServerEnum3,     api_RNetServerEnum3}, /* anon OK */
    57865541        {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms},
    5787         {"SetUserPassword",     RAP_WUserPasswordSet2,  api_SetUserPassword},
    57885542        {"WWkstaUserLogon",     RAP_WWkstaUserLogon,    api_WWkstaUserLogon},
    57895543        {"PrintJobInfo",        RAP_WPrintJobSetInfo,   api_PrintJobInfo},
  • trunk/server/source3/smbd/mangle_hash2.c

    r745 r862  
    627627                if (((unsigned int)name[0]) > 128 && (name[1] != 0)) {
    628628                        /* Possible start of mb character. */
    629                         char mbc[2];
     629                        size_t size = 0;
     630                        (void)next_codepoint(name, &size);
    630631                        /*
    631632                         * Note that if CH_UNIX is utf8 a string may be 3
     
    635636                         * JRA.
    636637                         */
    637                         if (convert_string(CH_UNIX, CH_UTF16LE, name, 2, mbc, 2, False) == 2) {
    638                                 /* Was a good mb string. */
    639                                 name += 2;
     638                        if (size > 1) {
     639                                /* Was a mb string. */
     640                                name += size;
    640641                                continue;
    641642                        }
  • trunk/server/source3/smbd/msdfs.c

    r751 r862  
    975975                DEBUG(3,("get_referred_path: No valid referrals for path %s\n",
    976976                        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                }
    977990                goto err_exit;
    978991        }
  • trunk/server/source3/smbd/nttrans.c

    r751 r862  
    537537                                req->flags2 & FLAGS2_DFS_PATHNAMES,
    538538                                fname,
    539                                 0,
     539                                (create_disposition == FILE_CREATE)
     540                                        ? UCF_CREATING_FILE : 0,
    540541                                NULL,
    541542                                &smb_fname);
     
    886887        /* Ensure we have at least one thing set. */
    887888        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;
    895891        }
    896892
     
    990986                        break;
    991987                }
     988
     989                /* Integer wrap protection for the increment. */
     990                if (offset + next_offset < offset) {
     991                        break;
     992                }
     993
    992994                offset += next_offset;
     995
     996                /* Integer wrap protection for while loop. */
     997                if (offset + 4 < offset) {
     998                        break;
     999                }
     1000
    9931001        }
    9941002
     
    11591167                                req->flags2 & FLAGS2_DFS_PATHNAMES,
    11601168                                fname,
    1161                                 0,
     1169                                (create_disposition == FILE_CREATE)
     1170                                        ? UCF_CREATING_FILE : 0,
    11621171                                NULL,
    11631172                                &smb_fname);
  • trunk/server/source3/smbd/open.c

    r751 r862  
    5959        }
    6060
     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         */
    6168        return se_access_check(sd,
    6269                                token,
     
    143150
    144151        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
     159static 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);
    145194}
    146195
     
    14171466                        }
    14181467
    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;
    14201476                } else {
    14211477                        access_mask = FILE_GENERIC_ALL;
     
    19892045                        /*
    19902046                         * 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).
    19922048                         */
    19932049
    19942050                        if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
     2051                            !conn->sconn->using_smb2 &&
    19952052                            lp_defer_sharing_violations()) {
    19962053                                struct timeval timeout;
     
    27532810        mtimespec = smb_dname->st.st_ex_mtime;
    27542811
    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
    27572814#ifdef O_DIRECTORY
    27582815        status = fd_open(conn, fsp, O_RDONLY|O_DIRECTORY, 0);
     
    32133270                        DEBUG(10, ("Unable to stat stream: %s\n",
    32143271                                   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                        }
    32153291                }
    32163292
  • trunk/server/source3/smbd/oplock_linux.c

    r751 r862  
    7676{
    7777        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();
    7886
    7987        /* First set the signal handler. */
    8088        if (linux_set_lease_sighandler(fd) == -1) {
    81                 return -1;
     89                saved_errno = errno;
     90                ret = -1;
     91                goto out;
    8292        }
    8393        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        }
    98105        return ret;
    99106}
  • trunk/server/source3/smbd/posix_acls.c

    r751 r862  
    13731373                if (pace->type == SMB_ACL_USER_OBJ) {
    13741374
    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                                 */
    13761380                                apply_default_perms(params, is_directory, pace, S_IRUSR);
    13771381                        }
     
    14531457                        }
    14541458
    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);
    14581464                } else {
    14591465                        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  
    155155        }
    156156
    157         len = smb_len(buf_out) + 4;
     157        len = smb_len_large(buf_out) + 4;
    158158
    159159        ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
     
    923923        DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
    924924        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         }
    978925}
    979926
     
    20341981                 */
    20351982                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);
    20371985                if (req->chain_outbuf == NULL) {
    20381986                        smb_panic("talloc failed");
  • trunk/server/source3/smbd/proto.h

    r751 r862  
    770770/* The following definitions come from smbd/process.c  */
    771771
    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);
    775772bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
    776773                  bool no_signing, uint32_t seqnum,
     
    981978void reload_printers(struct tevent_context *ev,
    982979                     struct messaging_context *msg_ctx);
     980void reload_printers_full(struct tevent_context *ev,
     981                          struct messaging_context *msg_ctx);
    983982bool reload_services(struct messaging_context *msg_ctx, int smb_sock,
    984983                     bool test);
    985 void reload_pcap_change_notify(struct tevent_context *ev,
    986                                struct messaging_context *msg_ctx);
    987984void exit_server(const char *const explanation);
    988985void exit_server_cleanly(const char *const explanation);
  • trunk/server/source3/smbd/reply.c

    r751 r862  
    17491749        }
    17501750
     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
    17511759        status = filename_convert(ctx,
    17521760                                conn,
    17531761                                req->flags2 & FLAGS2_DFS_PATHNAMES,
    17541762                                fname,
    1755                                 0,
     1763                                (create_disposition == FILE_CREATE)
     1764                                        ? UCF_CREATING_FILE : 0,
    17561765                                NULL,
    17571766                                &smb_fname);
     
    17641773                }
    17651774                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);
    17741775                goto out;
    17751776        }
     
    19241925        }
    19251926
     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
    19261937        status = filename_convert(ctx,
    19271938                                conn,
    19281939                                req->flags2 & FLAGS2_DFS_PATHNAMES,
    19291940                                fname,
    1930                                 0,
     1941                                (create_disposition == FILE_CREATE)
     1942                                        ? UCF_CREATING_FILE : 0,
    19311943                                NULL,
    19321944                                &smb_fname);
     
    19391951                }
    19401952                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);
    19511953                goto out;
    19521954        }
     
    21462148                                req->flags2 & FLAGS2_DFS_PATHNAMES,
    21472149                                fname,
    2148                                 0,
     2150                                UCF_CREATING_FILE,
    21492151                                NULL,
    21502152                                &smb_fname);
     
    22402242        connection_struct *conn = req->conn;
    22412243        struct smb_filename *smb_fname = NULL;
     2244        char *wire_name = NULL;
    22422245        char *fname = NULL;
    22432246        uint32 fattr;
    22442247        files_struct *fsp;
    22452248        int oplock_request;
    2246         int tmpfd;
    22472249        char *s;
    22482250        NTSTATUS status;
     2251        int i;
    22492252        TALLOC_CTX *ctx = talloc_tos();
    22502253
     
    22592262        oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
    22602263
    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,
    22622265                            STR_TERMINATE, &status);
    22632266        if (!NT_STATUS_IS_OK(status)) {
     
    22652268                goto out;
    22662269        }
    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,
    22812289                                req->flags2 & FLAGS2_DFS_PATHNAMES,
    22822290                                fname,
    2283                                 0,
     2291                                UCF_CREATING_FILE,
    22842292                                NULL,
    22852293                                &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,
    22892297                                        ERRSRV, ERRbadpath);
     2298                                goto out;
     2299                        }
     2300                        reply_nterror(req, status);
    22902301                        goto out;
    22912302                }
     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... */
    22922343                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);
    23322344                goto out;
    23332345        }
     
    23702382 out:
    23712383        TALLOC_FREE(smb_fname);
     2384        TALLOC_FREE(fname);
     2385        TALLOC_FREE(wire_name);
    23722386        END_PROFILE(SMBctemp);
    23732387        return;
     
    31373151        START_PROFILE(SMBreadbraw);
    31383152
    3139         if (srv_is_signing_active(sconn) ||
    3140             is_encrypted_packet(req->inbuf)) {
     3153        if (srv_is_signing_active(sconn) || req->encrypted) {
    31413154                exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
    31423155                        "raw reads/writes are disallowed.");
     
    35313544        int saved_errno = 0;
    35323545
    3533         if(fsp_stat(fsp) == -1) {
    3534                 reply_nterror(req, map_nt_error_from_unix(errno));
    3535                 return;
    3536         }
    3537 
    35383546        init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
    35393547            (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
     
    35433551                reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
    35443552                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't
    3552                  * try the sendfile() path.
    3553                  */
    3554                 goto nosendfile_read;
    35553553        }
    35563554
     
    35623560
    35633561        if (!req_is_in_chain(req) &&
    3564             !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
     3562            !req->encrypted && (fsp->base_fsp == NULL) &&
    35653563            (fsp->wcp == NULL) &&
    35663564            lp_use_sendfile(SNUM(conn), req->sconn->smb1.signing_state) ) {
    35673565                uint8 headerbuf[smb_size + 12 * 2];
    35683566                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                }
    35693582
    35703583                /*
     
    37663779                        }
    37673780                        /* 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) {
    37703782                                reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
    37713783                                END_PROFILE(SMBreadX);
     
    55305542                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
    55315543                                 directory,
    5532                                  0,
     5544                                 UCF_CREATING_FILE,
    55335545                                 NULL,
    55345546                                 &smb_dname);
     
    61956207                          smb_fname_str_dbg(smb_fname_dst)));
    61966208
    6197                 if (!lp_posix_pathnames() &&
     6209                if (!fsp->is_directory &&
     6210                    !lp_posix_pathnames() &&
    61986211                    (lp_map_archive(SNUM(conn)) ||
    61996212                    lp_store_dos_attributes(SNUM(conn)))) {
  • trunk/server/source3/smbd/server.c

    r845 r862  
    2121   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    2222*/
    23 #ifdef __OS2__
    24 #define INCL_DOSEXCEPTIONS
    25 #define INCL_DOSPROCESS
    26 #define INCL_DOSMODULEMGR
    27 #define INCL_LOADEXCEPTQ
    28 #define INCL_FORKEXCEPTQ
    29 #include "os2.h"
    30 #include "exceptq.h"
    31 #undef FILE_CREATE
    32 #undef FILE_OPEN
    33 #endif
    3423
    3524#include "includes.h"
     
    120109        change_to_root_user();
    121110        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 */
    126112}
    127113
     
    143129        reload_printers(ev_ctx, msg);
    144130}
     131
     132static 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
     142static 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
     156static 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
     170static 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
    145182
    146183/*******************************************************************
     
    784821                           smb_stat_cache_delete);
    785822        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);
    788823        brl_register_msgs(msg_ctx);
    789824
     
    909944        NTSTATUS status;
    910945
    911 #ifdef __OS2__
    912         EXCEPTIONREGISTRATIONRECORD ExRegRec;
    913         LoadExceptq(&ExRegRec, NULL, NULL);
    914 #endif
    915946        /*
    916947         * Do this before any other talloc operation
     
    12641295                exit(1);
    12651296
    1266         /* Publish nt printers, this requires a working winreg pipe */
    1267         pcap_cache_reload(server_event_context(), smbd_messaging_context(),
    1268                           &reload_printers);
    1269 
    12701297        /* only start the background queue daemon if we are
    12711298           running as a daemon -- bad things will happen if
     
    12751302        if (is_daemon && !interactive
    12761303            && 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);
    12791317        }
    12801318
     
    13351373        exit_server_cleanly(NULL);
    13361374        TALLOC_FREE(frame);
    1337 #ifdef __OS2__
    1338         UninstallExceptq(&ExRegRec);
    1339 #endif
    13401375        return(0);
    13411376}
  • trunk/server/source3/smbd/server_reload.c

    r751 r862  
    3737                     struct messaging_context *msg_ctx)
    3838{
     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**************************************************************************/
     80void reload_printers_full(struct tevent_context *ev,
     81                          struct messaging_context *msg_ctx)
     82{
    3983        struct auth_serversupplied_info *session_info = NULL;
    40         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
    4184        int n_services;
    4285        int pnum;
     
    4689        NTSTATUS status;
    4790
    48         load_printers(ev, msg_ctx);
    49 
    5091        n_services = lp_numservices();
    5192        pnum = lp_servicenumber(PRINTERS_NAME);
    5293
    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);
    5695        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"));
    5997                /* can't remove stale printers before we
    6098                 * are fully initilized */
     
    82120                /* check printer, but avoid removing non-autoloaded printers */
    83121                if (lp_autoloaded(snum) && !pcap_printername_ok(pname)) {
    84                         DEBUG(3, ("removing stale printer %s\n", pname));
    85 
     122                        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
    86123                        if (is_printer_published(session_info, session_info,
    87124                                                 msg_ctx,
    88                                                  NULL, lp_servicename(snum),
    89                                                  NULL, &pinfo2)) {
     125                                                 NULL,
     126                                                 lp_servicename(snum),
     127                                                 &pinfo2)) {
    90128                                nt_printer_publish(session_info,
    91129                                                   session_info,
     
    97135                        nt_printer_remove(session_info, session_info, msg_ctx,
    98136                                          pname);
    99                         lp_killservice(snum);
    100137                } else {
    101138                        DEBUG(8, ("Adding default registry entry for printer "
     
    106143        }
    107144
    108         /* Make sure deleted printers are gone */
    109         load_printers(ev, msg_ctx);
     145        /* finally, purge old snums */
     146        reload_printers(ev, msg_ctx);
    110147
    111148        TALLOC_FREE(session_info);
     
    161198        return(ret);
    162199}
    163 
    164 /****************************************************************************
    165  Notify smbds of new printcap data
    166 **************************************************************************/
    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 that
    172          * newly added printers get default values created in the registry.
    173          *
    174          * This will block the process for some time (~1 sec per printer), but
    175          * 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  
    162162        /* Assume OS/2 users are smart enough to put a correct path in smb.conf, and simply copy the string */
    163163        safe_strcpy(destname, connectpath, strlen(connectpath));
    164 #endif 
     164#endif
    165165
    166166        DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
     
    662662                }
    663663
    664                 return make_serverinfo_from_username(mem_ctx, user, guest,
     664                return make_serverinfo_from_username(mem_ctx, user, guest, guest,
    665665                                                     presult);
    666666        }
     
    696696
    697697                status = make_serverinfo_from_username(
    698                         conn, fuser, conn->session_info->guest,
     698                        conn, fuser, false, conn->session_info->guest,
    699699                        &forced_serverinfo);
    700700                if (!NT_STATUS_IS_OK(status)) {
  • trunk/server/source3/smbd/sesssetup.c

    r751 r862  
    910910                        (unsigned int)pblob->length ));
    911911
     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
    912919                tmp_blob = data_blob(NULL,
    913920                                pad->partial_data.length + copy_len);
     
    11701177        status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1);
    11711178        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);
    11721185                if (!NT_STATUS_EQUAL(status,
    11731186                                NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     
    11761189                }
    11771190                data_blob_free(&blob1);
    1178                 reply_nterror(req, nt_status_squash(status));
    11791191                return;
    11801192        }
  • trunk/server/source3/smbd/smb2_create.c

    r751 r862  
    695695                                          smb1req->flags2 & FLAGS2_DFS_PATHNAMES,
    696696                                          fname,
    697                                           0,
     697                                          (in_create_disposition == FILE_CREATE) ?
     698                                                UCF_CREATING_FILE : 0,
    698699                                          NULL,
    699700                                          &smb_fname);
     
    894895                return false;
    895896        }
    896         if (!smb2req->async) {
    897                 return false;
    898         }
    899897        req = smb2req->subreq;
    900898        if (!req) {
     
    903901        state = tevent_req_data(req, struct smbd_smb2_create_state);
    904902        if (!state) {
     903                return false;
     904        }
     905        if (!state->open_was_deferred) {
    905906                return false;
    906907        }
  • trunk/server/source3/smbd/smb2_getinfo.c

    r751 r862  
    149149        }
    150150
    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))) {
    152155                /* Return a specific error with data. */
    153156                error = smbd_smb2_request_error_ex(req,
     
    186189        outdyn = out_output_buffer;
    187190
    188         error = smbd_smb2_request_done(req, outbody, &outdyn);
     191        error = smbd_smb2_request_done_ex(req, call_status, outbody, &outdyn, __location__);
    189192        if (!NT_STATUS_IS_OK(error)) {
    190193                smbd_server_connection_terminate(req->sconn,
     
    271274
    272275        switch (in_info_type) {
    273         case 0x01:/* SMB2_GETINFO_FILE */
     276        case SMB2_GETINFO_FILE:
    274277        {
    275278                uint16_t file_info_level;
     
    282285                int lock_data_count = 0;
    283286                char *lock_data = NULL;
     287                size_t fixed_portion;
    284288
    285289                ZERO_STRUCT(write_time_ts);
     
    369373                                               STR_UNICODE,
    370374                                               in_output_buffer_length,
     375                                               &fixed_portion,
    371376                                               &data,
    372377                                               &data_size);
     
    377382                        }
    378383                        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);
    379390                        return tevent_req_post(req, ev);
    380391                }
     
    387398                                return tevent_req_post(req, ev);
    388399                        }
     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                        }
    389405                }
    390406                SAFE_FREE(data);
     
    392408        }
    393409
    394         case 0x02:/* SMB2_GETINFO_FS */
     410        case SMB2_GETINFO_FS:
    395411        {
    396412                uint16_t file_info_level;
    397413                char *data = NULL;
    398414                int data_size = 0;
     415                size_t fixed_portion;
    399416
    400417                /* the levels directly map to the passthru levels */
     
    405422                                         STR_UNICODE,
    406423                                         in_output_buffer_length,
     424                                         &fixed_portion,
     425                                         fsp->fsp_name,
    407426                                         &data,
    408427                                         &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))) {
    410432                        SAFE_FREE(data);
    411433                        if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
     
    413435                        }
    414436                        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);
    415443                        return tevent_req_post(req, ev);
    416444                }
     
    423451                                return tevent_req_post(req, ev);
    424452                        }
     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                        }
    425458                }
    426459                SAFE_FREE(data);
     
    428461        }
    429462
    430         case 0x03:/* SMB2_GETINFO_SEC */
     463        case SMB2_GETINFO_SECURITY:
    431464        {
    432465                uint8_t *p_marshalled_sd = NULL;
     
    485518        }
    486519
     520        state->status = status;
    487521        tevent_req_done(req);
    488522        return tevent_req_post(req, ev);
  • trunk/server/source3/smbd/smb2_server.c

    r751 r862  
    928928        uint64_t message_id = 0;
    929929        uint64_t async_id = 0;
    930         struct iovec *outvec = NULL;
    931930
    932931        if (!tevent_req_is_in_progress(subreq)) {
     
    945944                /*
    946945                 * 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                }
    957967        }
    958968
     
    963973        }
    964974
    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.
    970982                 */
    971983                status = smb2_send_async_interim_response(req);
     
    974986                }
    975987
    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                }
    9891018        }
    9901019
    9911020        /* Don't return an intermediate packet on a pipe read/write. */
    9921021        if (req->tcon && req->tcon->compat_conn && IS_IPC(req->tcon->compat_conn)) {
    993                 goto ipc_out;
     1022                goto out;
    9941023        }
    9951024
     
    10811110        /* Note we're going async with this request. */
    10821111        req->async = true;
    1083 
    1084   ipc_out:
    1085 
    1086         /*
    1087          * Now manipulate req so that the outstanding async request
    1088          * 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 must
    1111          * 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;
    11271112
    11281113  out:
     
    11781163                uint64_t message_id;
    11791164                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                }
    11801173
    11811174                i = cur->current_idx;
     
    13611354        if (flags & SMB2_HDR_FLAG_CHAINED) {
    13621355                req->compound_related = true;
    1363                 req->sconn->smb2.compound_related_in_progress = true;
    13641356        }
    13651357
     
    18031795                        return NT_STATUS_NO_MEMORY;
    18041796                }
     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
    18051816                tevent_schedule_immediate(im,
    18061817                                        req->sconn->smb2.event_ctx,
     
    18121823        if (req->compound_related) {
    18131824                req->compound_related = false;
    1814                 req->sconn->smb2.compound_related_in_progress = false;
    18151825        }
    18161826
     
    25292539        struct tevent_req *subreq;
    25302540
    2531         if (sconn->smb2.compound_related_in_progress) {
    2532                 /*
    2533                  * Can't read another until the related
    2534                  * compound is done.
    2535                  */
    2536                 return NT_STATUS_OK;
    2537         }
    2538 
    25392541        if (tevent_queue_length(sconn->smb2.recv_queue) > 0) {
    25402542                /*
  • trunk/server/source3/smbd/smb2_tcon.c

    r751 r862  
    208208        }
    209209
     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
    210219        /* create a new tcon as child of the session */
    211220        tcon = talloc_zero(req->session, struct smbd_smb2_tcon);
  • trunk/server/source3/smbd/trans2.c

    r792 r862  
    2525
    2626#include "includes.h"
     27#include "ntioctl.h"
    2728#include "system/filesys.h"
    2829#include "version.h"
     
    337338                }
    338339
     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
    339349                push_ascii_fstring(dos_ea_name, listp->ea.name);
    340350
     
    420430        uint8_t *p = (uint8_t *)pdata;
    421431        uint8_t *last_start = NULL;
     432        bool store_data = (pdata != NULL);
    422433
    423434        *ret_data_size = 0;
     
    431442                fstring dos_ea_name;
    432443                size_t this_size;
    433 
    434                 if (last_start) {
     444                size_t pad = 0;
     445
     446                if (last_start && store_data) {
    435447                        SIVAL(last_start, 0, PTR_DIFF(p, last_start));
    436448                }
     
    449461
    450462                if (ea_list->next) {
    451                         size_t pad = 4 - (this_size % 4);
     463                        pad = (4 - (this_size % 4)) % 4;
    452464                        this_size += pad;
    453465                }
     
    458470
    459471                /* 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                }
    466485
    467486                total_data_size -= this_size;
     
    477496{
    478497        size_t total_ea_len = 0;
     498        struct ea_list *ea_list = NULL;
    479499        TALLOC_CTX *mem_ctx = NULL;
    480500
     
    483503        }
    484504        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
    486530        return total_ea_len;
    487531}
     
    17441788                SIVAL(p,0,mode); p += 4;
    17451789                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 {
    17471793                        unsigned int ea_size = estimate_ea_size(conn, NULL,
    17481794                                                                smb_fname->base_name);
    17491795                        SIVAL(p,0,ea_size); /* Extended attributes */
    1750                         p += 4;
    1751                 }
     1796                }
     1797                p += 4;
    17521798                /* Clear the short name buffer. This is
    17531799                 * IMPORTANT as not doing so will trigger
     
    19211967                SIVAL(p,0,mode); p += 4;
    19221968                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 {
    19241972                        unsigned int ea_size = estimate_ea_size(conn, NULL,
    19251973                                                                smb_fname->base_name);
    19261974                        SIVAL(p,0,ea_size); /* Extended attributes */
    1927                         p +=4;
    1928                 }
     1975                }
     1976                p +=4;
    19291977                SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
    19301978                SBVAL(p,0,file_index); p += 8;
     
    19672015                SIVAL(p,0,mode); p += 4;
    19682016                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 {
    19702020                        unsigned int ea_size = estimate_ea_size(conn, NULL,
    19712021                                                                smb_fname->base_name);
    19722022                        SIVAL(p,0,ea_size); /* Extended attributes */
    1973                         p +=4;
    1974                 }
     2023                }
     2024                p +=4;
    19752025                /* Clear the short name buffer. This is
    19762026                 * IMPORTANT as not doing so will trigger
     
    29352985                         uint16_t flags2,
    29362986                         unsigned int max_data_bytes,
     2987                         size_t *fixed_portion,
     2988                         struct smb_filename *fname,
    29372989                         char **ppdata,
    29382990                         int *ret_data_len)
     
    29432995        int snum = SNUM(conn);
    29442996        char *fstype = lp_fstype(SNUM(conn));
     2997        const char *filename = NULL;
    29452998        uint32 additional_flags = 0;
    2946         struct smb_filename smb_fname_dot;
     2999        struct smb_filename smb_fname;
    29473000        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        }
    29483008
    29493009        if (IS_IPC(conn)) {
     
    29583018        DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
    29593019
    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) {
    29643024                DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
    29653025                return map_nt_error_from_unix(errno);
    29663026        }
    29673027
    2968         st = smb_fname_dot.st;
     3028        st = smb_fname.st;
    29693029
    29703030        *ppdata = (char *)SMB_REALLOC(
     
    29773037        memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
    29783038        end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
     3039
     3040        *fixed_portion = 0;
    29793041
    29803042        switch (info_level) {
     
    29833045                        uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
    29843046                        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) {
    29863048                                return map_nt_error_from_unix(errno);
    29873049                        }
     
    30703132                        SIVAL(pdata,8,len);
    30713133                        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;
    30723141                        break;
    30733142
     
    30993168                        DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
    31003169                                (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
    31013177                        break;
    31023178
     
    31063182                        uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
    31073183                        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) {
    31093185                                return map_nt_error_from_unix(errno);
    31103186                        }
     
    31313207                        SIVAL(pdata,16,sectors_per_unit);
    31323208                        SIVAL(pdata,20,bytes_per_sector);
     3209                        *fixed_portion = 24;
    31333210                        break;
    31343211                }
     
    31383215                        uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
    31393216                        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) {
    31413218                                return map_nt_error_from_unix(errno);
    31423219                        }
     
    31643241                        SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
    31653242                        SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
     3243                        *fixed_portion = 32;
    31663244                        break;
    31673245                }
     
    31783256                        SIVAL(pdata,0,FILE_DEVICE_DISK); /* dev type */
    31793257                        SIVAL(pdata,4,characteristics);
     3258                        *fixed_portion = 8;
    31803259                        break;
    31813260                }
     
    33313410                        }
    33323411
    3333                         rc = SMB_VFS_STATVFS(conn, ".", &svfs);
     3412                        rc = SMB_VFS_STATVFS(conn, filename, &svfs);
    33343413
    33353414                        if (!rc) {
     
    33523431                                return NT_STATUS_DOS(ERRSRV, ERRerror);
    33533432                        }
     3433                        *fixed_portion = 24;
    33543434                        break;
    33553435                }
     
    34823562
    34833563        *ret_data_len = data_len;
    3484         return NT_STATUS_OK;
     3564        return status;
    34853565}
    34863566
     
    34983578        uint16_t info_level;
    34993579        int data_len = 0;
     3580        size_t fixed_portion;
    35003581        NTSTATUS status;
    35013582
     
    35243605                                 req->flags2,
    35253606                                 max_data_bytes,
     3607                                 &fixed_portion,
     3608                                 NULL,
    35263609                                 ppdata, &data_len);
    35273610        if (!NT_STATUS_IS_OK(status)) {
     
    40764159        unsigned int ofs = 0;
    40774160
    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++) {
    40794166                unsigned int next_offset;
    40804167                size_t namelen;
     
    40954182                namelen -= 2;
    40964183
     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
    40974194                SIVAL(data, ofs+4, namelen);
    40984195                SOFF_T(data, ofs+8, streams[i].size);
     
    41094206                        unsigned int align = ndr_align_size(next_offset, 8);
    41104207
     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
    41114216                        memset(data+next_offset, 0, align);
    41124217                        next_offset += align;
     
    41184223                ofs = next_offset;
    41194224        }
     4225
     4226        DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes, ofs));
    41204227
    41214228        *data_size = ofs;
     
    42074314                               uint16_t flags2,
    42084315                               unsigned int max_data_bytes,
     4316                               size_t *fixed_portion,
    42094317                               char **ppdata,
    42104318                               unsigned int *pdata_size)
     
    43424450        file_index = get_FileIndex(conn, psbuf);
    43434451
     4452        *fixed_portion = 0;
     4453
    43444454        switch (info_level) {
    43454455                case SMB_INFO_STANDARD:
     
    44794589                        DEBUG(5,("change: %s ", ctime(&c_time)));
    44804590                        DEBUG(5,("mode: %x\n", mode));
     4591                        *fixed_portion = data_size;
    44814592                        break;
    44824593
     
    44924603                        SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
    44934604                        SSVAL(pdata,22,0); /* Padding. */
     4605                        *fixed_portion = 24;
    44944606                        break;
    44954607
     
    45014613                        DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
    45024614                        data_size = 4;
     4615                        *fixed_portion = 4;
    45034616                        SIVAL(pdata,0,ea_size);
    45044617                        break;
     
    45224635                        data_size = 4 + len;
    45234636                        SIVAL(pdata,0,len);
     4637                        *fixed_portion = 8;
    45244638                        break;
    45254639                }
     
    45854699                        pdata += 4 + len;
    45864700                        data_size = PTR_DIFF(pdata,(*ppdata));
     4701                        *fixed_portion = 10;
    45874702                        break;
    45884703                }
     
    46224737                        pdata += 4 + len;
    46234738                        data_size = PTR_DIFF(pdata,(*ppdata));
     4739                        *fixed_portion = 104;
    46244740                        break;
    46254741                }
     
    46294745                        SBVAL(pdata, 0, file_index);
    46304746                        data_size = 8;
     4747                        *fixed_portion = 8;
    46314748                        break;
    46324749
     
    46354752                        SIVAL(pdata, 0, access_mask);
    46364753                        data_size = 4;
     4754                        *fixed_portion = 4;
    46374755                        break;
    46384756
     
    46524770                        data_size = 1;
    46534771                        SCVAL(pdata,0,delete_pending);
     4772                        *fixed_portion = 1;
    46544773                        break;
    46554774
     
    46584777                        data_size = 8;
    46594778                        SOFF_T(pdata,0,pos);
     4779                        *fixed_portion = 8;
    46604780                        break;
    46614781
     
    46644784                        SIVAL(pdata,0,mode);
    46654785                        data_size = 4;
     4786                        *fixed_portion = 4;
    46664787                        break;
    46674788
     
    46704791                        SIVAL(pdata,0,0); /* No alignment needed. */
    46714792                        data_size = 4;
     4793                        *fixed_portion = 4;
    46724794                        break;
    46734795
     
    47084830                                DEBUG(10, ("marshall_stream_info failed: %s\n",
    47094831                                           nt_errstr(status)));
     4832                                TALLOC_FREE(streams);
    47104833                                return status;
    47114834                        }
    47124835
    47134836                        TALLOC_FREE(streams);
     4837
     4838                        *fixed_portion = 32;
    47144839
    47154840                        break;
     
    47224847                        SIVAL(pdata,12,0); /* ??? */
    47234848                        data_size = 16;
     4849                        *fixed_portion = 16;
    47244850                        break;
    47254851
     
    47354861                        SIVAL(pdata,52,0); /* ??? */
    47364862                        data_size = 56;
     4863                        *fixed_portion = 56;
    47374864                        break;
    47384865
     
    47424869                        SIVAL(pdata,4,0);
    47434870                        data_size = 8;
     4871                        *fixed_portion = 8;
    47444872                        break;
    47454873
     
    50115139        int lock_data_count = 0;
    50125140        char *lock_data = NULL;
     5141        size_t fixed_portion;
    50135142        NTSTATUS status = NT_STATUS_OK;
    50145143
     
    53725501                                       lock_data_count, lock_data,
    53735502                                       req->flags2, max_data_bytes,
     5503                                       &fixed_portion,
    53745504                                       ppdata, &data_size);
    53755505        if (!NT_STATUS_IS_OK(status)) {
    53765506                reply_nterror(req, status);
     5507                return;
     5508        }
     5509        if (fixed_portion > max_data_bytes) {
     5510                reply_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH);
    53775511                return;
    53785512        }
     
    73257459                        create_disp = FILE_OPEN_IF;
    73267460                        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
    73277470                case 0:
    73287471                        /* File exists open. File not exist fail. */
    73297472                        create_disp = FILE_OPEN;
    73307473                        break;
    7331                 case SMB_O_EXCL:
    7332                         /* O_EXCL on its own without O_CREAT is undefined. */
    73337474                default:
    73347475                        DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
     
    75837724                        }
    75847725                        /* Fail with sharing violation. */
     7726                        TALLOC_FREE(lck);
    75857727                        close_file(req, fsp, NORMAL_CLOSE);
    7586                         TALLOC_FREE(lck);
    75877728                        return NT_STATUS_SHARING_VIOLATION;
    75887729                }
     
    75987739                                                smb_fname);
    75997740
     7741        TALLOC_FREE(lck);
     7742
    76007743        if (!NT_STATUS_IS_OK(status)) {
    76017744                close_file(req, fsp, NORMAL_CLOSE);
    7602                 TALLOC_FREE(lck);
    76037745                return status;
    76047746        }
    7605         TALLOC_FREE(lck);
    76067747        return close_file(req, fsp, NORMAL_CLOSE);
    76077748}
Note: See TracChangeset for help on using the changeset viewer.