hierynomus / smbj

Server Message Block (SMB2, SMB3) implementation in Java
Other
709 stars 181 forks source link

SMBApiException: STATUS_REQUEST_NOT_ACCEPTED (0xc00000d0) #557

Open AlexHsu85 opened 4 years ago

AlexHsu85 commented 4 years ago

hi i'm new to use smbj 0.8.0 for changing SMB1 into SMB2 ,and i have some problems

here's my code in SmbFileUtilForSmb2.class:

public static DiskShare createSmbFile(String ip, String shareFolderName, String aUser, String aPasswd)throws IOException {
    SMBClient client = null;
    Connection connection = null;
    Session session = null;
    try {
        SmbConfig smbConfig = SmbConfig.builder().withMultiProtocolNegotiate(true)
            .withTransportLayerFactory(new AsyncDirectTcpTransportFactory<()).withSigningRequired(true)
                    .build();
            client = new SMBClient(smbConfig);
            AuthenticationContext ac = new AuthenticationContext(aUser, aPasswd.toCharArray(), null);
            connection = client.connect(ip);
            session = connection.authenticate(ac);
            DiskShare diskShare = (DiskShare) session.connectShare(shareFolderName);
            return diskShare;
        } catch (SMBApiException sae) {
            if (session != null)
                session.close();
            if (connection != null)
                connection.close();
            if (client != null)
                client.close();

            throw new IOException(sae);
        }
    }

public static void createFile(String aTarget, String aUser, String aPasswd, String aContent) throws IOException {
        Map<String, String> splitMap = this.splitUrl(aTarget);
        String ip = splitMap.get("ip");
        String shareFolderName = splitMap.get("shareFolderName");
        String filePath = splitMap.get("filePath");

        DiskShare diskShare = null;
        diskShare = createSmbFile(ip, shareFolderName, aUser, aPasswd);
        File file = null;
        OutputStream os = null;

        try {
            int idx = filePath.lastIndexOf("/");
            if (idx > -1) {
                String folder = filePath.substring(0, idx);

                String parentFolder = "";
                StringTokenizer st = new StringTokenizer(folder, "/");
                while(st.hasMoreTokens()){
                    parentFolder +=st.nextToken().toString();

                    if(!diskShare.folderExists(parentFolder))
                    diskShare.mkdir(parentFolder);

                    parentFolder += "/";
                }

            }

            if (!diskShare.fileExists(filePath)) {
                file = diskShare.openFile(filePath, new HashSet<>(Arrays.asList(AccessMask.GENERIC_ALL)),
                        new HashSet<>(Arrays.asList(FileAttributes.FILE_ATTRIBUTE_NORMAL)), SMB2ShareAccess.ALL,
                        SMB2CreateDisposition.FILE_CREATE,
                        new HashSet<>(Arrays.asList(SMB2CreateOptions.FILE_DIRECTORY_FILE)));

            } else {
                System.out.println("File has existed");
            }

            if (file == null) {
                if (diskShare != null)
                    diskShare.close();      
                return;
            }

            os = file.getOutputStream();
            os.write(aContent.getBytes("UTF-8"));
        } catch (SMBApiException sae) {
            sae.printStackTrace();
            throw new IOException(sae);
        } finally {
            if (os != null)
                os.close();
            if (diskShare != null)
                diskShare.close();
        }

    }

    public static void deleteFile(String aTarget, String aUser, String aPasswd) throws IOException {
        Map<String, String> splitMap = this.splitUrl(aTarget);
        String ip = splitMap.get("ip");
        String shareFolderName = splitMap.get("shareFolderName");
        String filePath = splitMap.get("filePath");

        DiskShare diskShare = createSmbFile(ip, shareFolderName, aUser, aPasswd);
        try {
            if(filePath.lastIndexOf(".") > -1 && diskShare.fileExists(filePath)){
                diskShare.rm(filePath);
            }else if(diskShare.folderExists(filePath)){
                diskShare.rmdir(filePath, true);
            }
        } catch (SMBApiException sae) {
            throw new IOException(sae);
        } finally {
            if (diskShare != null)
                diskShare.close();
        }
    }

    public static boolean exists(String aTarget, String aUser, String aPasswd) throws IOException {
        boolean isFileExist = false;
        DiskShare diskShare = null;

        Map<String, String> splitMap = this.splitUrl(aTarget);
        String ip = splitMap.get("ip");
        String shareFolderName = splitMap.get("shareFolderName");
        String filePath = splitMap.get("filePath");

        try {
            diskShare = createSmbFile(ip, shareFolderName, aUser, aPasswd);

            int idx = filePath.lastIndexOf("/");
            if (idx > -1) {
                String folder = filePath.substring(0, idx);
                if (!diskShare.folderExists(folder)){
                    return isFileExist;
                }
            }

            isFileExist = diskShare.fileExists(filePath);
        } catch (SMBApiException sae) {
            throw new IOException(sae);
        } finally {
            if(diskShare != null){
                diskShare.close();
            }
        }

        return isFileExist;
    }

    public static void mkdirs(String aTarget, String aUser, String aPasswd) throws IOException {
        DiskShare diskShare = null;

        Map<String, String> splitMap = this.splitUrl(aTarget);
        String ip = splitMap.get("ip");
        String shareFolderName = splitMap.get("shareFolderName");
        String filePath = splitMap.get("filePath");

        try {
            diskShare = createSmbFile(ip, shareFolderName, aUser, aPasswd);

            String parentFolder = "";
            StringTokenizer st = new StringTokenizer(filePath, "/");
            while(st.hasMoreTokens()){
                parentFolder +=st.nextToken().toString();

                if(!diskShare.folderExists(parentFolder))
                diskShare.mkdir(parentFolder);

                parentFolder += "/";
            }

        } catch (SMBApiException sae) {
            throw new IOException(sae);
        } finally {
            if (diskShare != null)
                diskShare.close();
        }
    }

    public static void copyFileTo(String aSource, String aUser, String aPasswd, String aTarget) throws IOException {
        DiskShare diskShare = null;

        Map<String, String> splitMap = this.splitUrl(aTarget);
        String ip = splitMap.get("ip");
        String shareFolderName = splitMap.get("shareFolderName");
        String filePath = splitMap.get("filePath");

        try {
            diskShare = createSmbFile(ip, shareFolderName, aUser, aPasswd);

            int idx = filePath.lastIndexOf("/");
            if (idx > -1) {
                String folder = filePath.substring(0, idx);

                String parentFolder = "";
                StringTokenizer st = new StringTokenizer(folder, "/");
                while (st.hasMoreTokens()) {
                    parentFolder += st.nextToken().toString();

                    if (!diskShare.folderExists(parentFolder))
                        diskShare.mkdir(parentFolder);

                    parentFolder += "/";
                }

            }

            java.io.File file = new java.io.File(aSource);

            SmbFiles.copy(file, diskShare, filePath, true);
        } catch (java.io.FileNotFoundException | NullPointerException ex) {
            throw new IOException(ex);
        } finally {
            if (diskShare != null)
                diskShare.close();
        }
    }

and I wrote an api to invoke something code like this as below and looped 3~4 times:


      String dataPath = "http://10.1.21.197/Custom/folder1/dataTest.txt";
      String aSource = "C:\Users\alex\AppData";
      String userId = "alex";
      String password = "123"
      String jsonString = gson.toJson(testDataDTO); //Json String

    if (SmbFileUtilForSmb2.exists(dataPath, userId, password))
        SmbFileUtilForSmb2.deleteFile(dataPath, userId, password);
    SmbFileUtilForSmb2.mkdirs(folderPath, userId, password);
    SmbFileUtilForSmb2.createFile(dataPath, userId, password, jsonString);

        SmbFileUtilForSmb2.copyFileTo(aSource, userId, password, aTarget);

and I am getting the following log and SMBApiException :

INFO c.c.a.d.s.s.TestService - ready to write data INFO c.h.smbj.connection.Connection - Successfully connected to: 10.1.21.197 INFO c.h.smbj.connection.Connection - Successfully authenticated alex on 10.1.21.197, session is 136339508953137 INFO com.hierynomus.smbj.session.Session - Connecting to \10.1.21.197\Custom on session 136339508953137 INFO c.h.smbj.connection.Connection - Successfully connected to: 10.1.21.197 INFO c.h.smbj.connection.Connection - Successfully authenticated alex on 10.1.21.197, session is 136339508953141 INFO com.hierynomus.smbj.session.Session - Connecting to \10.1.21.197\Custom on session 136339508953141 INFO c.h.smbj.connection.Connection - Successfully connected to: 10.1.21.197 INFO c.h.smbj.connection.Connection - Successfully authenticated alex on 10.1.21.197, session is 136339508953145 INFO com.hierynomus.smbj.session.Session - Connecting to \10.1.21.197\Custom on session 136339508953145 INFO c.h.smbj.connection.Connection - Successfully connected to: 10.1.21.197 INFO c.h.smbj.connection.Connection - Successfully authenticated alex on 10.1.21.197, session is 136339508953149 INFO com.hierynomus.smbj.session.Session - Connecting to \10.1.21.197\Custom on session 136339508953149 INFO c.c.a.d.s.s.TestService - finish to write data

INFO c.h.smbj.connection.Connection - Successfully connected to: 10.1.21.197 INFO c.h.smbj.connection.Connection - Successfully authenticated alex on 10.1.21.197, session is 136339508953153 INFO com.hierynomus.smbj.session.Session - Connecting to \10.1.21.197\Custom on session 136339508953153 INFO c.h.smbj.connection.Connection - Successfully connected to: 10.1.21.197 INFO c.h.smbj.connection.Connection - Successfully authenticated alex on 10.1.21.197, session is 136339508953157 INFO com.hierynomus.smbj.session.Session - Connecting to \10.1.21.197\Custom on session 136339508953157 INFO c.h.smbj.connection.Connection - Successfully connected to: 10.1.21.197 INFO c.h.smbj.connection.Connection - Successfully authenticated alex on 10.1.21.197, session is 136339508953161 INFO com.hierynomus.smbj.session.Session - Connecting to \10.1.21.197\Custom on session 136339508953161 INFO c.c.a.d.s.s.TestService - ready to write data INFO c.h.smbj.connection.Connection - Successfully connected to: 10.1.21.197 INFO c.h.smbj.connection.Connection - Successfully authenticated alex on 10.1.21.197, session is 136339508953165 INFO com.hierynomus.smbj.session.Session - Connecting to \10.1.21.197\Custom on session 136339508953165 INFO c.c.a.d.s.s.TestService - finish to write data

INFO c.h.smbj.connection.Connection - Successfully connected to: 10.1.21.197 INFO c.h.smbj.connection.Connection - Closed connection to 10.1.21.197 INFO com.hierynomus.smbj.SMBClient - Going to close all remaining connections

INFO c.h.smbj.connection.Connection - Successfully connected to: 10.1.21.197 INFO c.h.smbj.connection.Connection - Closed connection to 10.1.21.197 INFO com.hierynomus.smbj.SMBClient - Going to close all remaining connections

INFO c.c.a.d.s.s.TestService - com.hierynomus.mssmb2.SMBApiException: STATUS_REQUEST_NOT_ACCEPTED (0xc00000d0): Authentication failed for 'alex' using com.hierynomus.smbj.auth.NtlmAuthenticator@c99cf2b

INFO c.h.smbj.connection.Connection - Successfully connected to: 10.1.21.197 INFO c.h.smbj.connection.Connection - Closed connection to 10.1.21.197 INFO com.hierynomus.smbj.SMBClient - Going to close all remaining connections INFO c.c.a.d.s.c.TestController - errorMessage: com.hierynomus.mssmb2.SMBApiException: STATUS_REQUEST_NOT_ACCEPTED (0xc00000d0): Authentication failed for 'alex' using com.hierynomus.smbj.auth.NtlmAuthenticator@1ba3b059

INFO c.h.smbj.connection.Connection - Successfully connected to: 10.1.21.197 INFO c.h.smbj.connection.Connection - Closed connection to 10.1.21.197 INFO com.hierynomus.smbj.SMBClient - Going to close all remaining connections

Can anyone help me with it. appreciate solving problems !

hierynomus commented 3 years ago

As it works the first few times around, my guess is that something on the server prevents you from creating too many successive connections. You would need to look into the server logs to see why it fails the authentication with that error code.

hierynomus commented 3 years ago

There are a few possible causes to this error code described here: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e545352b-9f2b-4c5e-9350-db46e4f6755e

hierynomus commented 3 years ago

Any update to this @AlexHsu85 ?