34
34
wbcErr wbcAuthenticateUser(const char *username,
35
35
const char *password)
37
wbcErr wbc_status = WBC_ERR_SUCCESS;
38
struct wbcAuthUserParams params;
42
params.account_name = username;
43
params.level = WBC_AUTH_USER_LEVEL_PLAIN;
44
params.password.plaintext = password;
46
wbc_status = wbcAuthenticateUserEx(¶ms, NULL, NULL);
47
BAIL_ON_WBC_ERROR(wbc_status);
53
static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
54
const struct winbindd_response *resp,
55
struct wbcAuthUserInfo **_i)
57
wbcErr wbc_status = WBC_ERR_SUCCESS;
58
struct wbcAuthUserInfo *i;
59
struct wbcDomainSid domain_sid;
64
i = talloc(mem_ctx, struct wbcAuthUserInfo);
65
BAIL_ON_PTR_ERROR(i, wbc_status);
67
i->user_flags = resp->data.auth.info3.user_flgs;
69
i->account_name = talloc_strdup(i, resp->data.auth.info3.user_name);
70
BAIL_ON_PTR_ERROR(i->account_name, wbc_status);
71
i->user_principal= NULL;
72
i->full_name = talloc_strdup(i, resp->data.auth.info3.full_name);
73
BAIL_ON_PTR_ERROR(i->full_name, wbc_status);
74
i->domain_name = talloc_strdup(i, resp->data.auth.info3.logon_dom);
75
BAIL_ON_PTR_ERROR(i->domain_name, wbc_status);
76
i->dns_domain_name= NULL;
78
i->acct_flags = resp->data.auth.info3.acct_flags;
79
memcpy(i->user_session_key,
80
resp->data.auth.user_session_key,
81
sizeof(i->user_session_key));
82
memcpy(i->lm_session_key,
83
resp->data.auth.first_8_lm_hash,
84
sizeof(i->lm_session_key));
86
i->logon_count = resp->data.auth.info3.logon_count;
87
i->bad_password_count = resp->data.auth.info3.bad_pw_count;
89
i->logon_time = resp->data.auth.info3.logon_time;
90
i->logoff_time = resp->data.auth.info3.logoff_time;
91
i->kickoff_time = resp->data.auth.info3.kickoff_time;
92
i->pass_last_set_time = resp->data.auth.info3.pass_last_set_time;
93
i->pass_can_change_time = resp->data.auth.info3.pass_can_change_time;
94
i->pass_must_change_time= resp->data.auth.info3.pass_must_change_time;
96
i->logon_server = talloc_strdup(i, resp->data.auth.info3.logon_srv);
97
BAIL_ON_PTR_ERROR(i->logon_server, wbc_status);
98
i->logon_script = talloc_strdup(i, resp->data.auth.info3.logon_script);
99
BAIL_ON_PTR_ERROR(i->logon_script, wbc_status);
100
i->profile_path = talloc_strdup(i, resp->data.auth.info3.profile_path);
101
BAIL_ON_PTR_ERROR(i->profile_path, wbc_status);
102
i->home_directory= talloc_strdup(i, resp->data.auth.info3.home_dir);
103
BAIL_ON_PTR_ERROR(i->home_directory, wbc_status);
104
i->home_drive = talloc_strdup(i, resp->data.auth.info3.dir_drive);
105
BAIL_ON_PTR_ERROR(i->home_drive, wbc_status);
108
i->num_sids += resp->data.auth.info3.num_groups;
109
i->num_sids += resp->data.auth.info3.num_other_sids;
111
i->sids = talloc_array(i, struct wbcSidWithAttr, i->num_sids);
112
BAIL_ON_PTR_ERROR(i->sids, wbc_status);
114
wbc_status = wbcStringToSid(resp->data.auth.info3.dom_sid,
116
BAIL_ON_WBC_ERROR(wbc_status);
118
#define _SID_COMPOSE(s, d, r, a) { \
120
if ((s).sid.num_auths < WBC_MAXSUBAUTHS) { \
121
(s).sid.sub_auths[(s).sid.num_auths++] = r; \
123
wbc_status = WBC_ERR_INVALID_SID; \
124
BAIL_ON_WBC_ERROR(wbc_status); \
126
(s).attributes = a; \
130
_SID_COMPOSE(i->sids[sn], domain_sid,
131
resp->data.auth.info3.user_rid,
134
_SID_COMPOSE(i->sids[sn], domain_sid,
135
resp->data.auth.info3.group_rid,
139
p = (char *)resp->extra_data.data;
141
wbc_status = WBC_ERR_INVALID_RESPONSE;
142
BAIL_ON_WBC_ERROR(wbc_status);
145
for (j=0; j < resp->data.auth.info3.num_groups; j++) {
150
char *e = strchr(p, '\n');
152
wbc_status = WBC_ERR_INVALID_RESPONSE;
153
BAIL_ON_WBC_ERROR(wbc_status);
158
ret = sscanf(s, "0x%08X:0x%08X", &rid, &attrs);
160
wbc_status = WBC_ERR_INVALID_RESPONSE;
161
BAIL_ON_WBC_ERROR(wbc_status);
164
_SID_COMPOSE(i->sids[sn], domain_sid,
169
for (j=0; j < resp->data.auth.info3.num_other_sids; j++) {
174
char *e = strchr(p, '\n');
176
wbc_status = WBC_ERR_INVALID_RESPONSE;
177
BAIL_ON_WBC_ERROR(wbc_status);
184
wbc_status = WBC_ERR_INVALID_RESPONSE;
185
BAIL_ON_WBC_ERROR(wbc_status);
190
ret = sscanf(a, "0x%08X",
193
wbc_status = WBC_ERR_INVALID_RESPONSE;
194
BAIL_ON_WBC_ERROR(wbc_status);
197
wbc_status = wbcStringToSid(s, &i->sids[sn].sid);
198
BAIL_ON_WBC_ERROR(wbc_status);
200
i->sids[sn].attributes = attrs;
213
static wbcErr wbc_create_error_info(TALLOC_CTX *mem_ctx,
214
const struct winbindd_response *resp,
215
struct wbcAuthErrorInfo **_e)
217
wbcErr wbc_status = WBC_ERR_SUCCESS;
218
struct wbcAuthErrorInfo *e;
220
e = talloc(mem_ctx, struct wbcAuthErrorInfo);
221
BAIL_ON_PTR_ERROR(e, wbc_status);
223
e->nt_status = resp->data.auth.nt_status;
224
e->pam_error = resp->data.auth.pam_error;
225
e->nt_string = talloc_strdup(e, resp->data.auth.nt_status_string);
226
BAIL_ON_PTR_ERROR(e->nt_string, wbc_status);
228
e->display_string = talloc_strdup(e, resp->data.auth.error_string);
229
BAIL_ON_PTR_ERROR(e->display_string, wbc_status);
239
/** @brief Authenticate with more detailed information
241
* @param params Input parameters, WBC_AUTH_USER_LEVEL_HASH
242
* is not supported yet
243
* @param info Output details on WBC_ERR_SUCCESS
244
* @param error Output details on WBC_ERR_AUTH_ERROR
249
wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params,
250
struct wbcAuthUserInfo **info,
251
struct wbcAuthErrorInfo **error)
37
253
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
38
255
struct winbindd_request request;
39
256
struct winbindd_response response;
258
ZERO_STRUCT(request);
259
ZERO_STRUCT(response);
266
wbc_status = WBC_ERR_INVALID_PARAM;
267
BAIL_ON_WBC_ERROR(wbc_status);
270
if (!params->account_name) {
42
271
wbc_status = WBC_ERR_INVALID_PARAM;
43
272
BAIL_ON_WBC_ERROR(wbc_status);
46
275
/* Initialize request */
277
switch (params->level) {
278
case WBC_AUTH_USER_LEVEL_PLAIN:
279
cmd = WINBINDD_PAM_AUTH;
280
request.flags = WBFLAG_PAM_INFO3_TEXT |
281
WBFLAG_PAM_USER_SESSION_KEY |
284
if (!params->password.plaintext) {
285
wbc_status = WBC_ERR_INVALID_PARAM;
286
BAIL_ON_WBC_ERROR(wbc_status);
289
if (params->domain_name && params->domain_name[0]) {
290
/* We need to get the winbind separator :-( */
291
struct winbindd_response sep_response;
293
ZERO_STRUCT(sep_response);
295
wbc_status = wbcRequestResponse(WINBINDD_INFO,
296
NULL, &sep_response);
297
BAIL_ON_WBC_ERROR(wbc_status);
299
snprintf(request.data.auth.user,
300
sizeof(request.data.auth.user)-1,
303
sep_response.data.info.winbind_separator,
304
params->account_name);
306
strncpy(request.data.auth.user,
307
params->account_name,
308
sizeof(request.data.auth.user)-1);
310
strncpy(request.data.auth.pass,
311
params->password.plaintext,
312
sizeof(request.data.auth.user)-1);
315
case WBC_AUTH_USER_LEVEL_HASH:
316
wbc_status = WBC_ERR_NOT_IMPLEMENTED;
317
BAIL_ON_WBC_ERROR(wbc_status);
320
case WBC_AUTH_USER_LEVEL_RESPONSE:
321
cmd = WINBINDD_PAM_AUTH_CRAP;
322
request.flags = WBFLAG_PAM_INFO3_TEXT |
323
WBFLAG_PAM_USER_SESSION_KEY |
326
if (params->password.response.lm_length &&
327
!params->password.response.lm_data) {
328
wbc_status = WBC_ERR_INVALID_PARAM;
329
BAIL_ON_WBC_ERROR(wbc_status);
331
if (params->password.response.lm_length == 0 &&
332
params->password.response.lm_data) {
333
wbc_status = WBC_ERR_INVALID_PARAM;
334
BAIL_ON_WBC_ERROR(wbc_status);
337
if (params->password.response.nt_length &&
338
!params->password.response.nt_data) {
339
wbc_status = WBC_ERR_INVALID_PARAM;
340
BAIL_ON_WBC_ERROR(wbc_status);
342
if (params->password.response.nt_length == 0&&
343
params->password.response.nt_data) {
344
wbc_status = WBC_ERR_INVALID_PARAM;
345
BAIL_ON_WBC_ERROR(wbc_status);
348
strncpy(request.data.auth_crap.user,
349
params->account_name,
350
sizeof(request.data.auth_crap.user)-1);
351
if (params->domain_name) {
352
strncpy(request.data.auth_crap.domain,
354
sizeof(request.data.auth_crap.domain)-1);
356
if (params->workstation_name) {
357
strncpy(request.data.auth_crap.workstation,
358
params->workstation_name,
359
sizeof(request.data.auth_crap.workstation)-1);
362
request.data.auth_crap.logon_parameters =
363
params->parameter_control;
365
memcpy(request.data.auth_crap.chal,
366
params->password.response.challenge,
367
sizeof(request.data.auth_crap.chal));
369
request.data.auth_crap.lm_resp_len =
370
MIN(params->password.response.lm_length,
371
sizeof(request.data.auth_crap.lm_resp));
372
request.data.auth_crap.nt_resp_len =
373
MIN(params->password.response.nt_length,
374
sizeof(request.data.auth_crap.nt_resp));
375
if (params->password.response.lm_data) {
376
memcpy(request.data.auth_crap.lm_resp,
377
params->password.response.lm_data,
378
request.data.auth_crap.lm_resp_len);
380
if (params->password.response.nt_data) {
381
memcpy(request.data.auth_crap.nt_resp,
382
params->password.response.nt_data,
383
request.data.auth_crap.nt_resp_len);
391
wbc_status = WBC_ERR_INVALID_PARAM;
392
BAIL_ON_WBC_ERROR(wbc_status);
395
wbc_status = wbcRequestResponse(cmd,
398
if (response.data.auth.nt_status != 0) {
400
wbc_status = wbc_create_error_info(NULL,
403
BAIL_ON_WBC_ERROR(wbc_status);
406
wbc_status = WBC_ERR_AUTH_ERROR;
407
BAIL_ON_WBC_ERROR(wbc_status);
409
BAIL_ON_WBC_ERROR(wbc_status);
412
wbc_status = wbc_create_auth_info(NULL,
415
BAIL_ON_WBC_ERROR(wbc_status);
419
if (response.extra_data.data)
420
free(response.extra_data.data);
425
/** @brief Trigger a verification of the trust credentials of a specific domain
427
* @param *domain The name of the domain, only NULL for the default domain is
428
* supported yet. Other values than NULL will result in
429
* WBC_ERR_NOT_IMPLEMENTED.
430
* @param error Output details on WBC_ERR_AUTH_ERROR
435
wbcErr wbcCheckTrustCredentials(const char *domain,
436
struct wbcAuthErrorInfo **error)
438
struct winbindd_request request;
439
struct winbindd_response response;
440
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
444
* the current protocol doesn't support
445
* specifying a domain
447
wbc_status = WBC_ERR_NOT_IMPLEMENTED;
448
BAIL_ON_WBC_ERROR(wbc_status);
48
451
ZERO_STRUCT(request);
49
452
ZERO_STRUCT(response);
51
/* dst is already null terminated from the memset above */
53
strncpy(request.data.auth.user, username,
54
sizeof(request.data.auth.user)-1);
55
strncpy(request.data.auth.pass, password,
56
sizeof(request.data.auth.user)-1);
58
wbc_status = wbcRequestResponse(WINBINDD_PAM_AUTH,
456
wbc_status = wbcRequestResponse(WINBINDD_CHECK_MACHACC,
459
if (response.data.auth.nt_status != 0) {
461
wbc_status = wbc_create_error_info(NULL,
464
BAIL_ON_WBC_ERROR(wbc_status);
467
wbc_status = WBC_ERR_AUTH_ERROR;
468
BAIL_ON_WBC_ERROR(wbc_status);
61
470
BAIL_ON_WBC_ERROR(wbc_status);
64
473
return wbc_status;