opcda icon indicating copy to clipboard operation
opcda copied to clipboard

Problem with access denied

Open DanielXavierJob opened this issue 11 months ago • 36 comments

Hello! Good afternoon, I was trying to use the library on a Windows Server 2012, and I received the following error: "make com object IOPCServer: Class not registered."

And soon after, I received the error: "make com object IOPCServer: access denied"

Looking for what happened, I discovered that you need to connect using DCOMSecurity

An example of using this would be like this:

  
   func ConfigureDCOMSecurity() error {
       // Defina as configurações de segurança COM usando as funções disponíveis
       err := com.CoInitializeSecurity(
           nil,
           -1,
           nil,
           nil,
           com.RPC_C_AUTHN_LEVEL_CONNECT,
           com.RPC_C_IMP_LEVEL_IMPERSONATE,
           nil,
           com.EOAC_NONE,
           nil,
       )
       return err
   }

There is a library that also makes this type of connection a-palchikov WMI and this one: go-ole COM

However, I don't know how difficult it would be to make this update and I would like to know from you if it is possible to help add this feature or where I should start to implement it.

DanielXavierJob avatar Apr 03 '25 18:04 DanielXavierJob

@DanielXavierJob If this API is needed, I can add it, but I'm not very familiar with DCOM security settings. How did you determine that calling this API is necessary? If it’s truly useful, it might very well solve issue #12.

I’m familiar with the go-ole project and have contributed code to it, but I don’t think OPC requires so many interfaces, so I didn’t reference go-ole

huskar-t avatar Apr 04 '25 15:04 huskar-t

@DanielXavierJob You can use the feat/com-security branch for testing, and the PR is #20.

huskar-t avatar Apr 04 '25 16:04 huskar-t

Thank you very much for your help and adding the rule! I will test it and give feedback!

DanielXavierJob avatar Apr 04 '25 16:04 DanielXavierJob

@DanielXavierJob Is there any progress?

huskar-t avatar Apr 05 '25 05:04 huskar-t

Good morning, we are testing here, on my machine the normal collection functionalities worked, however there is a specific machine whose configuration is very different, and it is with this implementation that you made that it should work, I will bring feedback until later.

DanielXavierJob avatar Apr 07 '25 11:04 DanielXavierJob

2025/04/07 10:36:28 ←[36m[INFO] Test connection OPC DA - Erro ao conectar ao ser
vidor OPC DA: make com object IOPCServer: Class not registered←[0m
2025/04/07 10:36:28 ←[32m[DEBUG] Test connection OPC DA - Conexão OPC DA fechada
←[0m
2025/04/07 10:36:28 http: panic serving [::1]:63313: runtime error: invalid memo
ry address or nil pointer dereference
goroutine 40 [running]:
net/http.(*conn).serve.func1()
        /usr/local/go/src/net/http/server.go:1947 +0xd4
panic({0x10b3320, 0x1740588})
        /usr/local/go/src/runtime/panic.go:785 +0xf6
github.com/huskar-t/opcda.NewOPCBrowser(0x0)
        /go/pkg/mod/github.com/huskar-t/[email protected]
08/opcbrowser.go:21 +0x23
github.com/huskar-t/opcda.(*OPCServer).CreateBrowser(...)
        /go/pkg/mod/github.com/huskar-t/[email protected]
08/opcserver.go:392
collector-opc-go/opc.(*OPCDAClient).Tree(0x427ac88, {0x471ce88, 0x1, 0x1})
        /workspace/opc/da.go:519 +0xac
collector-opc-go/app/api/opc.TestConnection(0x427a3c8)
        /workspace/app/api/opc/test_connection_win.go:50 +0x2fe
github.com/gin-gonic/gin.(*Context).Next(0x427a3c8)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:185 +0x30
collector-opc-go/api.(*APIManager).RegisterAPI.AuthMiddleware.func2(0x427a3c8)
        /workspace/api/middleware.go:8 +0x1f
github.com/gin-gonic/gin.(*Context).Next(...)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:185
github.com/gin-gonic/gin.LoggerWithConfig.func1(0x427a3c8)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/logger.go:249 +0xad
github.com/gin-gonic/gin.(*Context).Next(...)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:185
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0x4060468, 0x427a3c8)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:633 +0x74b
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0x4060468, {0x12d7d58, 0x427abe8},
0x4052428)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:589 +0x192
net/http.serverHandler.ServeHTTP({0x437e288}, {0x12d7d58, 0x427abe8}, 0x4052428)

        /usr/local/go/src/net/http/server.go:3210 +0x97
net/http.(*conn).serve(0x43624e0, {0x12d8310, 0x4350270})
        /usr/local/go/src/net/http/server.go:2092 +0x60a
created by net/http.(*Server).Serve in goroutine 1
        /usr/local/go/src/net/http/server.go:3360 +0x41a
2025/04/07 10:36:28 ←[36m[INFO] Test connection OPC DA - Erro ao conectar ao ser
vidor OPC DA: make com object IOPCServer: Class not registered←[0m
2025/04/07 10:36:28 ←[32m[DEBUG] Test connection OPC DA - Conexão OPC DA fechada
←[0m
2025/04/07 10:36:28 http: panic serving [::1]:63292: runtime error: invalid memo
ry address or nil pointer dereference
goroutine 34 [running]:
net/http.(*conn).serve.func1()
        /usr/local/go/src/net/http/server.go:1947 +0xd4
panic({0x10b3320, 0x1740588})
        /usr/local/go/src/runtime/panic.go:785 +0xf6
github.com/huskar-t/opcda.NewOPCBrowser(0x0)
        /go/pkg/mod/github.com/huskar-t/[email protected]
08/opcbrowser.go:21 +0x23
github.com/huskar-t/opcda.(*OPCServer).CreateBrowser(...)
        /go/pkg/mod/github.com/huskar-t/[email protected]
08/opcserver.go:392
collector-opc-go/opc.(*OPCDAClient).Tree(0x4290be8, {0x471cf48, 0x1, 0x1})
        /workspace/opc/da.go:519 +0xac
collector-opc-go/app/api/opc.TestConnection(0x41f99a8)
        /workspace/app/api/opc/test_connection_win.go:50 +0x2fe
github.com/gin-gonic/gin.(*Context).Next(0x41f99a8)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:185 +0x30
collector-opc-go/api.(*APIManager).RegisterAPI.AuthMiddleware.func2(0x41f99a8)
        /workspace/api/middleware.go:8 +0x1f
github.com/gin-gonic/gin.(*Context).Next(...)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:185
github.com/gin-gonic/gin.LoggerWithConfig.func1(0x41f99a8)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/logger.go:249 +0xad
github.com/gin-gonic/gin.(*Context).Next(...)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:185
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0x4060468, 0x41f99a8)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:633 +0x74b
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0x4060468, {0x12d7d58, 0x4290b48},
0x409cd18)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:589 +0x192
net/http.serverHandler.ServeHTTP({0x437e288}, {0x12d7d58, 0x4290b48}, 0x409cd18)

        /usr/local/go/src/net/http/server.go:3210 +0x97
net/http.(*conn).serve(0x4362300, {0x12d8310, 0x4350270})
        /usr/local/go/src/net/http/server.go:2092 +0x60a
created by net/http.(*Server).Serve in goroutine 1
        /usr/local/go/src/net/http/server.go:3360 +0x41a
2025/04/07 10:36:28 ←[36m[INFO] Test connection OPC DA - Erro ao conectar ao ser
vidor OPC DA: make com object IOPCServer: Class not registered←[0m
2025/04/07 10:36:28 ←[32m[DEBUG] Test connection OPC DA - Conexão OPC DA fechada
←[0m
2025/04/07 10:36:28 http: panic serving [::1]:63291: runtime error: invalid memo
ry address or nil pointer dereference
goroutine 32 [running]:
net/http.(*conn).serve.func1()
        /usr/local/go/src/net/http/server.go:1947 +0xd4
panic({0x10b3320, 0x1740588})
        /usr/local/go/src/runtime/panic.go:785 +0xf6
github.com/huskar-t/opcda.NewOPCBrowser(0x0)
        /go/pkg/mod/github.com/huskar-t/[email protected]
08/opcbrowser.go:21 +0x23
github.com/huskar-t/opcda.(*OPCServer).CreateBrowser(...)
        /go/pkg/mod/github.com/huskar-t/[email protected]
08/opcserver.go:392
collector-opc-go/opc.(*OPCDAClient).Tree(0x427b548, {0x471d0c0, 0x1, 0x1})
        /workspace/opc/da.go:519 +0xac
collector-opc-go/app/api/opc.TestConnection(0x427b4a8)
        /workspace/app/api/opc/test_connection_win.go:50 +0x2fe
github.com/gin-gonic/gin.(*Context).Next(0x427b4a8)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:185 +0x30
collector-opc-go/api.(*APIManager).RegisterAPI.AuthMiddleware.func2(0x427b4a8)
        /workspace/api/middleware.go:8 +0x1f
github.com/gin-gonic/gin.(*Context).Next(...)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:185
github.com/gin-gonic/gin.LoggerWithConfig.func1(0x427b4a8)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/logger.go:249 +0xad
github.com/gin-gonic/gin.(*Context).Next(...)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:185
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0x4060468, 0x427b4a8)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:633 +0x74b
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0x4060468, {0x12d7d58, 0x427b2c8},
0x4052588)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:589 +0x192
net/http.serverHandler.ServeHTTP({0x437e288}, {0x12d7d58, 0x427b2c8}, 0x4052588)

        /usr/local/go/src/net/http/server.go:3210 +0x97
net/http.(*conn).serve(0x4362180, {0x12d8310, 0x4350270})
        /usr/local/go/src/net/http/server.go:2092 +0x60a
created by net/http.(*Server).Serve in goroutine 1
        /usr/local/go/src/net/http/server.go:3360 +0x41a
2025/04/07 10:36:28 ←[36m[INFO] Test connection OPC DA - Erro ao conectar ao ser
vidor OPC DA: make com object IOPCServer: Class not registered←[0m
2025/04/07 10:36:28 ←[32m[DEBUG] Test connection OPC DA - Conexão OPC DA fechada
←[0m
2025/04/07 10:36:28 http: panic serving [::1]:63320: runtime error: invalid memo
ry address or nil pointer dereference
goroutine 45 [running]:
net/http.(*conn).serve.func1()
        /usr/local/go/src/net/http/server.go:1947 +0xd4
panic({0x10b3320, 0x1740588})
        /usr/local/go/src/runtime/panic.go:785 +0xf6
github.com/huskar-t/opcda.NewOPCBrowser(0x0)
        /go/pkg/mod/github.com/huskar-t/[email protected]
08/opcbrowser.go:21 +0x23
github.com/huskar-t/opcda.(*OPCServer).CreateBrowser(...)
        /go/pkg/mod/github.com/huskar-t/[email protected]
08/opcserver.go:392
collector-opc-go/opc.(*OPCDAClient).Tree(0x427b908, {0x471d240, 0x1, 0x1})
        /workspace/opc/da.go:519 +0xac
collector-opc-go/app/api/opc.TestConnection(0x427b868)
        /workspace/app/api/opc/test_connection_win.go:50 +0x2fe
github.com/gin-gonic/gin.(*Context).Next(0x427b868)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:185 +0x30
collector-opc-go/api.(*APIManager).RegisterAPI.AuthMiddleware.func2(0x427b868)
        /workspace/api/middleware.go:8 +0x1f
github.com/gin-gonic/gin.(*Context).Next(...)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:185
github.com/gin-gonic/gin.LoggerWithConfig.func1(0x427b868)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/logger.go:249 +0xad
github.com/gin-gonic/gin.(*Context).Next(...)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:185
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0x4060468, 0x427b868)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:633 +0x74b
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0x4060468, {0x12d7d58, 0x427b7c8},
0x40526e8)
        /go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:589 +0x192
net/http.serverHandler.ServeHTTP({0x437e288}, {0x12d7d58, 0x427b7c8}, 0x40526e8)

        /usr/local/go/src/net/http/server.go:3210 +0x97
net/http.(*conn).serve(0x4362600, {0x12d8310, 0x4350270})
        /usr/local/go/src/net/http/server.go:2092 +0x60a
created by net/http.(*Server).Serve in goroutine 1
        /usr/local/go/src/net/http/server.go:3360 +0x41a
2025/04/07 10:36:42 ←[31m[ERROR] Erro ao tentar buscar wrappers do OPC DA: Acces
s is denied.←[0m

DanielXavierJob avatar Apr 07 '25 14:04 DanielXavierJob

It has also given this error Image

DanielXavierJob avatar Apr 07 '25 14:04 DanielXavierJob

Based on the logs, there is a "Class not registered" error. You need to install the OPC Core Components from the following link: https://opcfoundation.org/developer-tools/samples-and-tools-classic/core-components/

huskar-t avatar Apr 07 '25 14:04 huskar-t

For the usage of CoInitializeSecurity, please refer to the link: https://github.com/huskar-t/opcda/blob/b71615d2cc5600ec445e3652ee5133fe6669aefa/opcserver_test.go#L30

huskar-t avatar Apr 07 '25 15:04 huskar-t

im utilizing this example and return "Access denied"

DanielXavierJob avatar Apr 07 '25 16:04 DanielXavierJob

My impersonation and Authenticate level is Auth None and Imp level Impersonate, but this error "Access denied" ocurring

DanielXavierJob avatar Apr 07 '25 16:04 DanielXavierJob

show your initialization code

huskar-t avatar Apr 08 '25 01:04 huskar-t

Try using the following combinations: err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, com.RPC_C_IMP_LEVEL_IMPERSONATE, com.EOAC_NONE) err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, com.RPC_C_IMP_LEVEL_IDENTIFY, com.EOAC_NONE) err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_CONNECT, com.RPC_C_IMP_LEVEL_IMPERSONATE, com.EOAC_NONE) err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_CONNECT, com.RPC_C_IMP_LEVEL_IDENTIFY, com.EOAC_NONE) err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_NONE, com.RPC_C_IMP_LEVEL_IDENTIFY, com.EOAC_NONE)

huskar-t avatar Apr 08 '25 02:04 huskar-t

show your initialization code


func GetImpersonateLevelAndAuthLevel() (uint32, uint32) {
	key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\OLE`, registry.QUERY_VALUE)
	if err != nil {
		fmt.Printf("Erro ao abrir a chave de registro: %v", err)
	}
	defer key.Close()

	impersonationLevel := uint32(0)
	authenticationLevel := uint32(0)
	valueInt, _, err := key.GetIntegerValue("LegacyAuthenticationLevel")
	if err != nil {
		fmt.Printf("Erro ao ler valor inteiro: %v", err)
	}
	authenticationLevel = uint32(valueInt)

	valueIntImpersonationLevel, _, err := key.GetIntegerValue("LegacyImpersonationLevel")
	if err != nil {
		fmt.Printf("Erro ao ler valor inteiro: %v", err)
	}
	impersonationLevel = uint32(valueIntImpersonationLevel)
	fmt.Printf("ImpersonateLevel: %d, AuthenticationLevel: %d\n", impersonationLevel, authenticationLevel)
	return impersonationLevel, authenticationLevel
}
func main() {
	com.Initialize()
	defer com.Uninitialize()
	impersonationLevel, authenticationLevel := GetImpersonateLevelAndAuthLevel()
	if err := com.CoInitializeSecurity(authenticationLevel, impersonationLevel, com.EOAC_NONE); err != nil {
		fmt.Printf("Erro ao inicializar segurança COM: %v", err)
	}

DanielXavierJob avatar Apr 08 '25 16:04 DanielXavierJob

Try using the following combinations: err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, com.RPC_C_IMP_LEVEL_IMPERSONATE, com.EOAC_NONE) err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, com.RPC_C_IMP_LEVEL_IDENTIFY, com.EOAC_NONE) err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_CONNECT, com.RPC_C_IMP_LEVEL_IMPERSONATE, com.EOAC_NONE) err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_CONNECT, com.RPC_C_IMP_LEVEL_IDENTIFY, com.EOAC_NONE) err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_NONE, com.RPC_C_IMP_LEVEL_IDENTIFY, com.EOAC_NONE)

Image

DanielXavierJob avatar Apr 08 '25 17:04 DanielXavierJob

Try using the following combinations: err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, com.RPC_C_IMP_LEVEL_IMPERSONATE, com.EOAC_NONE) err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, com.RPC_C_IMP_LEVEL_IDENTIFY, com.EOAC_NONE) err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_CONNECT, com.RPC_C_IMP_LEVEL_IMPERSONATE, com.EOAC_NONE) err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_CONNECT, com.RPC_C_IMP_LEVEL_IDENTIFY, com.EOAC_NONE) err := com.CoInitializeSecurity(com.RPC_C_AUTHN_LEVEL_NONE, com.RPC_C_IMP_LEVEL_IDENTIFY, com.EOAC_NONE)

Image

CoInitializeSecurity can only be initialized once per process, and each time a different combination should be used instead of directly calling all combinations at once.

huskar-t avatar Apr 09 '25 01:04 huskar-t

Access denied appears to be a DCOM configuration issue.

https://industrial.softing.com/de/services/faqs/opc-server-middleware/licensing-opc-general-data-integration-faqs.html

The error 0x80070005 (Access denied) indicates a DCOM problem.

The problem often lies in the user context used by COM/DCOM to launch the OPC Server (Microsoft DCOM Identity Setting).  

The Identity setting (dcomcnfg) also plays an important role by a local connection and even with our OPC Tunnel! In order to handle the underlying OPC Server in the OPC Tunnel correctly, the identity should be set to "Interactive User".

This identity setting is applicable only when running in Application Mode and not as “Service”. Please configure the OPC Server/Client as “Application” in the OPC Tray (Running Mode) and change the identity in the DCOM configuration (dcomcnfg).  

In the most cases this DCOM setting is helpful. Otherwise, please configure a user with administrator privileges and password and start the application under this user (on client and server sides).

The DCOM settings are however not part of our scope since the DCOM is a service of the Microsoft Windows operating system. For further information about it please visit the Microsoft Websites.

huskar-t avatar Apr 09 '25 01:04 huskar-t

I found this reference material. https://mybuilding.siemens.com/d015628993239/help/engineeringhelp/en-us/index.html#23567311755

huskar-t avatar Apr 09 '25 02:04 huskar-t

@DanielXavierJob Any progress?

huskar-t avatar Apr 11 '25 02:04 huskar-t

Hi, it still hasn't worked, we're investigating what's going on. We have two systems, one in Delphi and one in C# and both work without changing the DCOM settings, but I can't pass on any information about it, as they are private, currently I got an example of KaSSL OPC to test this connection.

DanielXavierJob avatar Apr 11 '25 11:04 DanielXavierJob

I still don't understand what's wrong with it not working.

DanielXavierJob avatar Apr 11 '25 11:04 DanielXavierJob

Hi, it still hasn't worked, we're investigating what's going on. We have two systems, one in Delphi and one in C# and both work without changing the DCOM settings, but I can't pass on any information about it, as they are private, currently I got an example of KaSSL OPC to test this connection.

Can you provide the libraries used for C# and Delphi?

huskar-t avatar Apr 12 '25 03:04 huskar-t

Does your system have multiple users?

huskar-t avatar Apr 12 '25 18:04 huskar-t

Hello! Sorry for the delay, we are still trying to solve it, the libraries used for connection were those of the OPC Foundation and Kassl.de

DanielXavierJob avatar Apr 17 '25 12:04 DanielXavierJob

Does your system have multiple users?

I can't tell you, but systems are generally one-to-one.

DanielXavierJob avatar Apr 17 '25 12:04 DanielXavierJob

I was able to make the connection using the free Kassl.de DLL for testing with C++

DanielXavierJob avatar Apr 17 '25 12:04 DanielXavierJob

Last week, I also encountered an Access denied issue. By checking the system logs, I found that a Guest account was used for the connection. You can also check the Windows system logs to see if there are any DCOM error logs.

huskar-t avatar Apr 17 '25 13:04 huskar-t

Hello, I saw that in this C# library it can connect using comProxyBlanket, maybe that's what's missing https://github.com/juan-minopex/TitaniumAS.Opc.Client

DanielXavierJob avatar Apr 17 '25 17:04 DanielXavierJob

Hello, here is the code I used that worked and returned the servers

Image

Image

DanielXavierJob avatar Apr 17 '25 19:04 DanielXavierJob

I have add CoSetProxyBlanket function, update the branch and call SetProxyBlanket. For example: https://github.com/huskar-t/opcda/blob/baad0397329c8e3f8725f2be7c4d5cfd972bd181/opcserver_test.go#L28-L40

huskar-t avatar Apr 18 '25 17:04 huskar-t