9
9
10
10
#include <wbclient.h>
11
11
12
+ #ifdef HAVE_PTHREAD
13
+ #include <pthread.h>
14
+
15
+ static pthread_key_t key ;
16
+ static pthread_once_t key_once = PTHREAD_ONCE_INIT ;
17
+
18
+ /* note that the destructor is given directly the content of the key in
19
+ * ptr, not the key itself. */
20
+ static void key_destructor (void * ptr )
21
+ {
22
+ wbcCtxFree ((struct wbcContext * )ptr );
23
+ }
24
+
25
+ static void key_create (void )
26
+ {
27
+ /* we have no way to report errors ... */
28
+ (void )pthread_key_create (& key , key_destructor );
29
+ }
30
+
31
+ static struct wbcContext * winbind_get_context (void )
32
+ {
33
+ struct wbcContext * ctx ;
34
+ int ret ;
35
+
36
+ ret = pthread_once (& key_once , key_create );
37
+ if (ret != 0 ) {
38
+ return NULL ;
39
+ }
40
+ ctx = pthread_getspecific (key );
41
+ if (ctx == NULL ) {
42
+ ctx = wbcCtxCreate ();
43
+ ret = pthread_setspecific (key , ctx );
44
+ if (ret != 0 ) {
45
+ wbcCtxFree (ctx );
46
+ ctx = NULL ;
47
+ }
48
+ }
49
+ return ctx ;
50
+ }
51
+
52
+ #else /* HAVE_PTHREAD */
53
+
54
+ /* non thread-safe version */
55
+ static struct wbcContext * gctx = NULL ;
56
+
57
+ static struct wbcContext * winbind_get_context (void )
58
+ {
59
+ if (gctx == NULL ) {
60
+ gctx = wbcCtxCreate ();
61
+ }
62
+ return gctx ;
63
+ }
64
+ #endif /* HAVE_PTHREAD */
65
+
12
66
uint32_t winbind_get_names (char * * computer , char * * domain )
13
67
{
68
+ struct wbcContext * ctx ;
14
69
struct wbcInterfaceDetails * details = NULL ;
15
70
wbcErr wbc_status ;
16
71
int ret = ERR_NOTAVAIL ;
17
72
18
- wbc_status = wbcInterfaceDetails (& details );
73
+ ctx = winbind_get_context ();
74
+ if (ctx == NULL ) {
75
+ ret = ERR_BADCTX ;
76
+ goto done ;
77
+ }
78
+
79
+ wbc_status = wbcCtxInterfaceDetails (ctx , & details );
19
80
if (!WBC_ERROR_IS_OK (wbc_status )) goto done ;
20
81
21
82
if (computer &&
@@ -51,17 +112,24 @@ uint32_t winbind_get_names(char **computer, char **domain)
51
112
uint32_t winbind_get_creds (struct gssntlm_name * name ,
52
113
struct gssntlm_cred * cred )
53
114
{
115
+ struct wbcContext * ctx ;
54
116
struct wbcCredentialCacheParams params ;
55
117
struct wbcCredentialCacheInfo * result ;
56
118
struct wbcInterfaceDetails * details = NULL ;
57
119
wbcErr wbc_status ;
58
120
bool cached = false;
59
121
int ret = ERR_NOTAVAIL ;
60
122
123
+ ctx = winbind_get_context ();
124
+ if (ctx == NULL ) {
125
+ ret = ERR_BADCTX ;
126
+ goto done ;
127
+ }
128
+
61
129
if (name && name -> data .user .domain ) {
62
130
params .domain_name = name -> data .user .domain ;
63
131
} else {
64
- wbc_status = wbcInterfaceDetails ( & details );
132
+ wbc_status = wbcCtxInterfaceDetails ( ctx , & details );
65
133
if (!WBC_ERROR_IS_OK (wbc_status )) goto done ;
66
134
67
135
params .domain_name = details -> netbios_domain ;
@@ -80,7 +148,7 @@ uint32_t winbind_get_creds(struct gssntlm_name *name,
80
148
params .level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP ;
81
149
params .num_blobs = 0 ;
82
150
params .blobs = NULL ;
83
- wbc_status = wbcCredentialCache ( & params , & result , NULL );
151
+ wbc_status = wbcCtxCredentialCache ( ctx , & params , & result , NULL );
84
152
85
153
if (WBC_ERROR_IS_OK (wbc_status )) {
86
154
/* Yes, winbind seems to think it has credentials for us */
@@ -120,6 +188,7 @@ uint32_t winbind_cli_auth(char *user, char *domain,
120
188
struct ntlm_key * exported_session_key )
121
189
{
122
190
/* Get responses and session key from winbind */
191
+ struct wbcContext * ctx ;
123
192
struct wbcCredentialCacheParams params ;
124
193
struct wbcCredentialCacheInfo * result = NULL ;
125
194
struct wbcNamedBlob * sesskey_blob = NULL ;
@@ -130,6 +199,12 @@ uint32_t winbind_cli_auth(char *user, char *domain,
130
199
int ret ;
131
200
int i ;
132
201
202
+ ctx = winbind_get_context ();
203
+ if (ctx == NULL ) {
204
+ ret = ERR_BADCTX ;
205
+ goto done ;
206
+ }
207
+
133
208
if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS ) {
134
209
/* Winbind doesn't support this (yet). We'd want to pass our
135
210
* own client_target_info in with the request. */
@@ -167,7 +242,7 @@ uint32_t winbind_cli_auth(char *user, char *domain,
167
242
}
168
243
}
169
244
170
- wbc_status = wbcCredentialCache ( & params , & result , NULL );
245
+ wbc_status = wbcCtxCredentialCache ( ctx , & params , & result , NULL );
171
246
if (!WBC_ERROR_IS_OK (wbc_status )) {
172
247
ret = ERR_NOTAVAIL ;
173
248
goto done ;
@@ -295,6 +370,7 @@ uint32_t winbind_srv_auth(char *user, char *domain,
295
370
struct ntlm_key * ntlmv2_key ,
296
371
struct gssntlm_name_attribute * * auth_attrs )
297
372
{
373
+ struct wbcContext * ctx ;
298
374
struct wbcAuthUserParams wbc_params = { 0 };
299
375
struct wbcAuthUserInfo * wbc_info = NULL ;
300
376
struct wbcAuthErrorInfo * wbc_err = NULL ;
@@ -306,6 +382,11 @@ uint32_t winbind_srv_auth(char *user, char *domain,
306
382
return ERR_KEYLEN ;
307
383
}
308
384
385
+ ctx = winbind_get_context ();
386
+ if (ctx == NULL ) {
387
+ return ERR_BADCTX ;
388
+ }
389
+
309
390
wbc_params .account_name = user ;
310
391
wbc_params .domain_name = domain ;
311
392
wbc_params .workstation_name = workstation ;
@@ -320,7 +401,8 @@ uint32_t winbind_srv_auth(char *user, char *domain,
320
401
wbc_params .password .response .lm_length = lm_chal_resp -> length ;
321
402
wbc_params .password .response .lm_data = lm_chal_resp -> data ;
322
403
323
- wbc_status = wbcAuthenticateUserEx (& wbc_params , & wbc_info , & wbc_err );
404
+ wbc_status = wbcCtxAuthenticateUserEx (ctx , & wbc_params , & wbc_info ,
405
+ & wbc_err );
324
406
325
407
if (!WBC_ERROR_IS_OK (wbc_status )) {
326
408
/* TODO: use wbcErrorString, to save error message */
0 commit comments