2 Unix SMB/CIFS implementation.
6 Copyright (C) Gerald (Jerry) Carter 2007
7 Copyright (C) Guenther Deschner 2008
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 3 of the License, or (at your option) any later version.
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /* Required Headers */
25 #include "libwbclient.h"
27 /** @brief Authenticate a username/password pair
29 * @param username Name of user to authenticate
30 * @param password Clear text password os user
35 wbcErr
wbcAuthenticateUser(const char *username
,
38 wbcErr wbc_status
= WBC_ERR_SUCCESS
;
39 struct wbcAuthUserParams params
;
43 params
.account_name
= username
;
44 params
.level
= WBC_AUTH_USER_LEVEL_PLAIN
;
45 params
.password
.plaintext
= password
;
47 wbc_status
= wbcAuthenticateUserEx(¶ms
, NULL
, NULL
);
48 BAIL_ON_WBC_ERROR(wbc_status
);
54 static wbcErr
wbc_create_auth_info(TALLOC_CTX
*mem_ctx
,
55 const struct winbindd_response
*resp
,
56 struct wbcAuthUserInfo
**_i
)
58 wbcErr wbc_status
= WBC_ERR_SUCCESS
;
59 struct wbcAuthUserInfo
*i
;
60 struct wbcDomainSid domain_sid
;
65 i
= talloc(mem_ctx
, struct wbcAuthUserInfo
);
66 BAIL_ON_PTR_ERROR(i
, wbc_status
);
68 i
->user_flags
= resp
->data
.auth
.info3
.user_flgs
;
70 i
->account_name
= talloc_strdup(i
, resp
->data
.auth
.info3
.user_name
);
71 BAIL_ON_PTR_ERROR(i
->account_name
, wbc_status
);
72 i
->user_principal
= NULL
;
73 i
->full_name
= talloc_strdup(i
, resp
->data
.auth
.info3
.full_name
);
74 BAIL_ON_PTR_ERROR(i
->full_name
, wbc_status
);
75 i
->domain_name
= talloc_strdup(i
, resp
->data
.auth
.info3
.logon_dom
);
76 BAIL_ON_PTR_ERROR(i
->domain_name
, wbc_status
);
77 i
->dns_domain_name
= NULL
;
79 i
->acct_flags
= resp
->data
.auth
.info3
.acct_flags
;
80 memcpy(i
->user_session_key
,
81 resp
->data
.auth
.user_session_key
,
82 sizeof(i
->user_session_key
));
83 memcpy(i
->lm_session_key
,
84 resp
->data
.auth
.first_8_lm_hash
,
85 sizeof(i
->lm_session_key
));
87 i
->logon_count
= resp
->data
.auth
.info3
.logon_count
;
88 i
->bad_password_count
= resp
->data
.auth
.info3
.bad_pw_count
;
90 i
->logon_time
= resp
->data
.auth
.info3
.logon_time
;
91 i
->logoff_time
= resp
->data
.auth
.info3
.logoff_time
;
92 i
->kickoff_time
= resp
->data
.auth
.info3
.kickoff_time
;
93 i
->pass_last_set_time
= resp
->data
.auth
.info3
.pass_last_set_time
;
94 i
->pass_can_change_time
= resp
->data
.auth
.info3
.pass_can_change_time
;
95 i
->pass_must_change_time
= resp
->data
.auth
.info3
.pass_must_change_time
;
97 i
->logon_server
= talloc_strdup(i
, resp
->data
.auth
.info3
.logon_srv
);
98 BAIL_ON_PTR_ERROR(i
->logon_server
, wbc_status
);
99 i
->logon_script
= talloc_strdup(i
, resp
->data
.auth
.info3
.logon_script
);
100 BAIL_ON_PTR_ERROR(i
->logon_script
, wbc_status
);
101 i
->profile_path
= talloc_strdup(i
, resp
->data
.auth
.info3
.profile_path
);
102 BAIL_ON_PTR_ERROR(i
->profile_path
, wbc_status
);
103 i
->home_directory
= talloc_strdup(i
, resp
->data
.auth
.info3
.home_dir
);
104 BAIL_ON_PTR_ERROR(i
->home_directory
, wbc_status
);
105 i
->home_drive
= talloc_strdup(i
, resp
->data
.auth
.info3
.dir_drive
);
106 BAIL_ON_PTR_ERROR(i
->home_drive
, wbc_status
);
109 i
->num_sids
+= resp
->data
.auth
.info3
.num_groups
;
110 i
->num_sids
+= resp
->data
.auth
.info3
.num_other_sids
;
112 i
->sids
= talloc_array(i
, struct wbcSidWithAttr
, i
->num_sids
);
113 BAIL_ON_PTR_ERROR(i
->sids
, wbc_status
);
115 wbc_status
= wbcStringToSid(resp
->data
.auth
.info3
.dom_sid
,
117 BAIL_ON_WBC_ERROR(wbc_status
);
119 #define _SID_COMPOSE(s, d, r, a) { \
121 if ((s).sid.num_auths < WBC_MAXSUBAUTHS) { \
122 (s).sid.sub_auths[(s).sid.num_auths++] = r; \
124 wbc_status = WBC_ERR_INVALID_SID; \
125 BAIL_ON_WBC_ERROR(wbc_status); \
127 (s).attributes = a; \
131 _SID_COMPOSE(i
->sids
[sn
], domain_sid
,
132 resp
->data
.auth
.info3
.user_rid
,
135 _SID_COMPOSE(i
->sids
[sn
], domain_sid
,
136 resp
->data
.auth
.info3
.group_rid
,
140 p
= (char *)resp
->extra_data
.data
;
142 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
143 BAIL_ON_WBC_ERROR(wbc_status
);
146 for (j
=0; j
< resp
->data
.auth
.info3
.num_groups
; j
++) {
151 char *e
= strchr(p
, '\n');
153 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
154 BAIL_ON_WBC_ERROR(wbc_status
);
159 ret
= sscanf(s
, "0x%08X:0x%08X", &rid
, &attrs
);
161 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
162 BAIL_ON_WBC_ERROR(wbc_status
);
165 _SID_COMPOSE(i
->sids
[sn
], domain_sid
,
170 for (j
=0; j
< resp
->data
.auth
.info3
.num_other_sids
; j
++) {
175 char *e
= strchr(p
, '\n');
177 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
178 BAIL_ON_WBC_ERROR(wbc_status
);
185 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
186 BAIL_ON_WBC_ERROR(wbc_status
);
191 ret
= sscanf(a
, "0x%08X",
194 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
195 BAIL_ON_WBC_ERROR(wbc_status
);
198 wbc_status
= wbcStringToSid(s
, &i
->sids
[sn
].sid
);
199 BAIL_ON_WBC_ERROR(wbc_status
);
201 i
->sids
[sn
].attributes
= attrs
;
214 static wbcErr
wbc_create_error_info(TALLOC_CTX
*mem_ctx
,
215 const struct winbindd_response
*resp
,
216 struct wbcAuthErrorInfo
**_e
)
218 wbcErr wbc_status
= WBC_ERR_SUCCESS
;
219 struct wbcAuthErrorInfo
*e
;
221 e
= talloc(mem_ctx
, struct wbcAuthErrorInfo
);
222 BAIL_ON_PTR_ERROR(e
, wbc_status
);
224 e
->nt_status
= resp
->data
.auth
.nt_status
;
225 e
->pam_error
= resp
->data
.auth
.pam_error
;
226 e
->nt_string
= talloc_strdup(e
, resp
->data
.auth
.nt_status_string
);
227 BAIL_ON_PTR_ERROR(e
->nt_string
, wbc_status
);
229 e
->display_string
= talloc_strdup(e
, resp
->data
.auth
.error_string
);
230 BAIL_ON_PTR_ERROR(e
->display_string
, wbc_status
);
240 static wbcErr
wbc_create_password_policy_info(TALLOC_CTX
*mem_ctx
,
241 const struct winbindd_response
*resp
,
242 struct wbcUserPasswordPolicyInfo
**_i
)
244 wbcErr wbc_status
= WBC_ERR_SUCCESS
;
245 struct wbcUserPasswordPolicyInfo
*i
;
247 i
= talloc(mem_ctx
, struct wbcUserPasswordPolicyInfo
);
248 BAIL_ON_PTR_ERROR(i
, wbc_status
);
250 i
->min_passwordage
= resp
->data
.auth
.policy
.min_passwordage
;
251 i
->min_length_password
= resp
->data
.auth
.policy
.min_length_password
;
252 i
->password_history
= resp
->data
.auth
.policy
.password_history
;
253 i
->password_properties
= resp
->data
.auth
.policy
.password_properties
;
254 i
->expire
= resp
->data
.auth
.policy
.expire
;
264 static wbcErr
wbc_create_logon_info(TALLOC_CTX
*mem_ctx
,
265 const struct winbindd_response
*resp
,
266 struct wbcLogonUserInfo
**_i
)
268 wbcErr wbc_status
= WBC_ERR_SUCCESS
;
269 struct wbcLogonUserInfo
*i
;
271 i
= talloc_zero(mem_ctx
, struct wbcLogonUserInfo
);
272 BAIL_ON_PTR_ERROR(i
, wbc_status
);
274 wbc_status
= wbc_create_auth_info(i
, resp
, &i
->info
);
275 BAIL_ON_WBC_ERROR(wbc_status
);
277 if (resp
->data
.auth
.krb5ccname
) {
278 wbc_status
= wbcAddNamedBlob(&i
->num_blobs
,
282 (uint8_t *)resp
->data
.auth
.krb5ccname
,
283 strlen(resp
->data
.auth
.krb5ccname
)+1);
284 BAIL_ON_WBC_ERROR(wbc_status
);
287 if (resp
->data
.auth
.unix_username
) {
288 wbc_status
= wbcAddNamedBlob(&i
->num_blobs
,
292 (uint8_t *)resp
->data
.auth
.unix_username
,
293 strlen(resp
->data
.auth
.unix_username
)+1);
294 BAIL_ON_WBC_ERROR(wbc_status
);
300 if (!WBC_ERROR_IS_OK(wbc_status
) && i
) {
301 wbcFreeMemory(i
->blobs
);
308 /** @brief Authenticate with more detailed information
310 * @param params Input parameters, WBC_AUTH_USER_LEVEL_HASH
311 * is not supported yet
312 * @param info Output details on WBC_ERR_SUCCESS
313 * @param error Output details on WBC_ERR_AUTH_ERROR
318 wbcErr
wbcAuthenticateUserEx(const struct wbcAuthUserParams
*params
,
319 struct wbcAuthUserInfo
**info
,
320 struct wbcAuthErrorInfo
**error
)
322 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
324 struct winbindd_request request
;
325 struct winbindd_response response
;
327 ZERO_STRUCT(request
);
328 ZERO_STRUCT(response
);
335 wbc_status
= WBC_ERR_INVALID_PARAM
;
336 BAIL_ON_WBC_ERROR(wbc_status
);
339 if (!params
->account_name
) {
340 wbc_status
= WBC_ERR_INVALID_PARAM
;
341 BAIL_ON_WBC_ERROR(wbc_status
);
344 /* Initialize request */
346 switch (params
->level
) {
347 case WBC_AUTH_USER_LEVEL_PLAIN
:
348 cmd
= WINBINDD_PAM_AUTH
;
349 request
.flags
= WBFLAG_PAM_INFO3_TEXT
|
350 WBFLAG_PAM_USER_SESSION_KEY
|
353 if (!params
->password
.plaintext
) {
354 wbc_status
= WBC_ERR_INVALID_PARAM
;
355 BAIL_ON_WBC_ERROR(wbc_status
);
358 if (params
->domain_name
&& params
->domain_name
[0]) {
359 /* We need to get the winbind separator :-( */
360 struct winbindd_response sep_response
;
362 ZERO_STRUCT(sep_response
);
364 wbc_status
= wbcRequestResponse(WINBINDD_INFO
,
365 NULL
, &sep_response
);
366 BAIL_ON_WBC_ERROR(wbc_status
);
368 snprintf(request
.data
.auth
.user
,
369 sizeof(request
.data
.auth
.user
)-1,
372 sep_response
.data
.info
.winbind_separator
,
373 params
->account_name
);
375 strncpy(request
.data
.auth
.user
,
376 params
->account_name
,
377 sizeof(request
.data
.auth
.user
)-1);
380 strncpy(request
.data
.auth
.pass
,
381 params
->password
.plaintext
,
382 sizeof(request
.data
.auth
.pass
)-1);
385 case WBC_AUTH_USER_LEVEL_HASH
:
386 wbc_status
= WBC_ERR_NOT_IMPLEMENTED
;
387 BAIL_ON_WBC_ERROR(wbc_status
);
390 case WBC_AUTH_USER_LEVEL_RESPONSE
:
391 cmd
= WINBINDD_PAM_AUTH_CRAP
;
392 request
.flags
= WBFLAG_PAM_INFO3_TEXT
|
393 WBFLAG_PAM_USER_SESSION_KEY
|
396 if (params
->password
.response
.lm_length
&&
397 !params
->password
.response
.lm_data
) {
398 wbc_status
= WBC_ERR_INVALID_PARAM
;
399 BAIL_ON_WBC_ERROR(wbc_status
);
401 if (params
->password
.response
.lm_length
== 0 &&
402 params
->password
.response
.lm_data
) {
403 wbc_status
= WBC_ERR_INVALID_PARAM
;
404 BAIL_ON_WBC_ERROR(wbc_status
);
407 if (params
->password
.response
.nt_length
&&
408 !params
->password
.response
.nt_data
) {
409 wbc_status
= WBC_ERR_INVALID_PARAM
;
410 BAIL_ON_WBC_ERROR(wbc_status
);
412 if (params
->password
.response
.nt_length
== 0&&
413 params
->password
.response
.nt_data
) {
414 wbc_status
= WBC_ERR_INVALID_PARAM
;
415 BAIL_ON_WBC_ERROR(wbc_status
);
418 strncpy(request
.data
.auth_crap
.user
,
419 params
->account_name
,
420 sizeof(request
.data
.auth_crap
.user
)-1);
421 if (params
->domain_name
) {
422 strncpy(request
.data
.auth_crap
.domain
,
424 sizeof(request
.data
.auth_crap
.domain
)-1);
426 if (params
->workstation_name
) {
427 strncpy(request
.data
.auth_crap
.workstation
,
428 params
->workstation_name
,
429 sizeof(request
.data
.auth_crap
.workstation
)-1);
432 request
.data
.auth_crap
.logon_parameters
=
433 params
->parameter_control
;
435 memcpy(request
.data
.auth_crap
.chal
,
436 params
->password
.response
.challenge
,
437 sizeof(request
.data
.auth_crap
.chal
));
439 request
.data
.auth_crap
.lm_resp_len
=
440 MIN(params
->password
.response
.lm_length
,
441 sizeof(request
.data
.auth_crap
.lm_resp
));
442 request
.data
.auth_crap
.nt_resp_len
=
443 MIN(params
->password
.response
.nt_length
,
444 sizeof(request
.data
.auth_crap
.nt_resp
));
445 if (params
->password
.response
.lm_data
) {
446 memcpy(request
.data
.auth_crap
.lm_resp
,
447 params
->password
.response
.lm_data
,
448 request
.data
.auth_crap
.lm_resp_len
);
450 if (params
->password
.response
.nt_data
) {
451 memcpy(request
.data
.auth_crap
.nt_resp
,
452 params
->password
.response
.nt_data
,
453 request
.data
.auth_crap
.nt_resp_len
);
461 wbc_status
= WBC_ERR_INVALID_PARAM
;
462 BAIL_ON_WBC_ERROR(wbc_status
);
466 request
.flags
|= params
->flags
;
469 wbc_status
= wbcRequestResponse(cmd
,
472 if (response
.data
.auth
.nt_status
!= 0) {
474 wbc_status
= wbc_create_error_info(NULL
,
477 BAIL_ON_WBC_ERROR(wbc_status
);
480 wbc_status
= WBC_ERR_AUTH_ERROR
;
481 BAIL_ON_WBC_ERROR(wbc_status
);
483 BAIL_ON_WBC_ERROR(wbc_status
);
486 wbc_status
= wbc_create_auth_info(NULL
,
489 BAIL_ON_WBC_ERROR(wbc_status
);
493 if (response
.extra_data
.data
)
494 free(response
.extra_data
.data
);
499 /** @brief Trigger a verification of the trust credentials of a specific domain
501 * @param *domain The name of the domain, only NULL for the default domain is
502 * supported yet. Other values than NULL will result in
503 * WBC_ERR_NOT_IMPLEMENTED.
504 * @param error Output details on WBC_ERR_AUTH_ERROR
509 wbcErr
wbcCheckTrustCredentials(const char *domain
,
510 struct wbcAuthErrorInfo
**error
)
512 struct winbindd_request request
;
513 struct winbindd_response response
;
514 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
518 * the current protocol doesn't support
519 * specifying a domain
521 wbc_status
= WBC_ERR_NOT_IMPLEMENTED
;
522 BAIL_ON_WBC_ERROR(wbc_status
);
525 ZERO_STRUCT(request
);
526 ZERO_STRUCT(response
);
530 wbc_status
= wbcRequestResponse(WINBINDD_CHECK_MACHACC
,
533 if (response
.data
.auth
.nt_status
!= 0) {
535 wbc_status
= wbc_create_error_info(NULL
,
538 BAIL_ON_WBC_ERROR(wbc_status
);
541 wbc_status
= WBC_ERR_AUTH_ERROR
;
542 BAIL_ON_WBC_ERROR(wbc_status
);
544 BAIL_ON_WBC_ERROR(wbc_status
);
550 /** @brief Trigger an extended logoff notification to Winbind for a specific user
552 * @param params A wbcLogoffUserParams structure
553 * @param error User output details on error
559 wbcErr
wbcLogoffUserEx(const struct wbcLogoffUserParams
*params
,
560 struct wbcAuthErrorInfo
**error
)
562 struct winbindd_request request
;
563 struct winbindd_response response
;
564 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
569 if (!params
|| !params
->username
) {
570 wbc_status
= WBC_ERR_INVALID_PARAM
;
571 BAIL_ON_WBC_ERROR(wbc_status
);
574 if ((params
->num_blobs
> 0) && (params
->blobs
== NULL
)) {
575 wbc_status
= WBC_ERR_INVALID_PARAM
;
576 BAIL_ON_WBC_ERROR(wbc_status
);
578 if ((params
->num_blobs
== 0) && (params
->blobs
!= NULL
)) {
579 wbc_status
= WBC_ERR_INVALID_PARAM
;
580 BAIL_ON_WBC_ERROR(wbc_status
);
583 ZERO_STRUCT(request
);
584 ZERO_STRUCT(response
);
586 strncpy(request
.data
.logoff
.user
, params
->username
,
587 sizeof(request
.data
.logoff
.user
)-1);
589 for (i
=0; i
<params
->num_blobs
; i
++) {
591 if (strcasecmp(params
->blobs
[i
].name
, "ccfilename") == 0) {
592 if (params
->blobs
[i
].blob
.data
) {
593 strncpy(request
.data
.logoff
.krb5ccname
,
594 (const char *)params
->blobs
[i
].blob
.data
,
595 sizeof(request
.data
.logoff
.krb5ccname
) - 1);
600 if (strcasecmp(params
->blobs
[i
].name
, "user_uid") == 0) {
601 if (params
->blobs
[i
].blob
.data
) {
602 memcpy(&request
.data
.logoff
.uid
,
603 params
->blobs
[i
].blob
.data
,
604 MIN(params
->blobs
[i
].blob
.length
,
605 sizeof(request
.data
.logoff
.uid
)));
610 if (strcasecmp(params
->blobs
[i
].name
, "flags") == 0) {
611 if (params
->blobs
[i
].blob
.data
) {
612 memcpy(&request
.flags
,
613 params
->blobs
[i
].blob
.data
,
614 MIN(params
->blobs
[i
].blob
.length
,
615 sizeof(request
.flags
)));
623 wbc_status
= wbcRequestResponse(WINBINDD_PAM_LOGOFF
,
627 /* Take the response above and return it to the caller */
628 if (response
.data
.auth
.nt_status
!= 0) {
630 wbc_status
= wbc_create_error_info(NULL
,
633 BAIL_ON_WBC_ERROR(wbc_status
);
636 wbc_status
= WBC_ERR_AUTH_ERROR
;
637 BAIL_ON_WBC_ERROR(wbc_status
);
639 BAIL_ON_WBC_ERROR(wbc_status
);
645 /** @brief Trigger a logoff notification to Winbind for a specific user
647 * @param username Name of user to remove from Winbind's list of
649 * @param uid Uid assigned to the username
650 * @param ccfilename Absolute path to the Krb5 credentials cache to
657 wbcErr
wbcLogoffUser(const char *username
,
659 const char *ccfilename
)
661 struct winbindd_request request
;
662 struct winbindd_response response
;
663 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
668 wbc_status
= WBC_ERR_INVALID_PARAM
;
669 BAIL_ON_WBC_ERROR(wbc_status
);
672 ZERO_STRUCT(request
);
673 ZERO_STRUCT(response
);
675 strncpy(request
.data
.logoff
.user
, username
,
676 sizeof(request
.data
.logoff
.user
)-1);
677 request
.data
.logoff
.uid
= uid
;
680 strncpy(request
.data
.logoff
.krb5ccname
, ccfilename
,
681 sizeof(request
.data
.logoff
.krb5ccname
)-1);
686 wbc_status
= wbcRequestResponse(WINBINDD_PAM_LOGOFF
,
690 /* Take the response above and return it to the caller */
696 /** @brief Change a password for a user with more detailed information upon
698 * @param params Input parameters
699 * @param error User output details on WBC_ERR_PWD_CHANGE_FAILED
700 * @param reject_reason New password reject reason on WBC_ERR_PWD_CHANGE_FAILED
701 * @param policy Password policy output details on WBC_ERR_PWD_CHANGE_FAILED
706 wbcErr
wbcChangeUserPasswordEx(const struct wbcChangePasswordParams
*params
,
707 struct wbcAuthErrorInfo
**error
,
708 enum wbcPasswordChangeRejectReason
*reject_reason
,
709 struct wbcUserPasswordPolicyInfo
**policy
)
711 struct winbindd_request request
;
712 struct winbindd_response response
;
713 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
718 if (!params
->account_name
) {
719 wbc_status
= WBC_ERR_INVALID_PARAM
;
720 BAIL_ON_WBC_ERROR(wbc_status
);
735 ZERO_STRUCT(request
);
736 ZERO_STRUCT(response
);
738 switch (params
->level
) {
739 case WBC_CHANGE_PASSWORD_LEVEL_PLAIN
:
740 cmd
= WINBINDD_PAM_CHAUTHTOK
;
742 if (!params
->account_name
) {
743 wbc_status
= WBC_ERR_INVALID_PARAM
;
744 BAIL_ON_WBC_ERROR(wbc_status
);
747 strncpy(request
.data
.chauthtok
.user
, params
->account_name
,
748 sizeof(request
.data
.chauthtok
.user
) - 1);
750 if (params
->old_password
.plaintext
) {
751 strncpy(request
.data
.chauthtok
.oldpass
,
752 params
->old_password
.plaintext
,
753 sizeof(request
.data
.chauthtok
.oldpass
) - 1);
756 if (params
->new_password
.plaintext
) {
757 strncpy(request
.data
.chauthtok
.newpass
,
758 params
->new_password
.plaintext
,
759 sizeof(request
.data
.chauthtok
.newpass
) - 1);
763 case WBC_CHANGE_PASSWORD_LEVEL_RESPONSE
:
764 cmd
= WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP
;
766 if (!params
->account_name
|| !params
->domain_name
) {
767 wbc_status
= WBC_ERR_INVALID_PARAM
;
768 BAIL_ON_WBC_ERROR(wbc_status
);
771 if (params
->old_password
.response
.old_lm_hash_enc_length
&&
772 !params
->old_password
.response
.old_lm_hash_enc_data
) {
773 wbc_status
= WBC_ERR_INVALID_PARAM
;
774 BAIL_ON_WBC_ERROR(wbc_status
);
777 if (params
->old_password
.response
.old_lm_hash_enc_length
== 0 &&
778 params
->old_password
.response
.old_lm_hash_enc_data
) {
779 wbc_status
= WBC_ERR_INVALID_PARAM
;
780 BAIL_ON_WBC_ERROR(wbc_status
);
783 if (params
->old_password
.response
.old_nt_hash_enc_length
&&
784 !params
->old_password
.response
.old_nt_hash_enc_data
) {
785 wbc_status
= WBC_ERR_INVALID_PARAM
;
786 BAIL_ON_WBC_ERROR(wbc_status
);
789 if (params
->old_password
.response
.old_nt_hash_enc_length
== 0 &&
790 params
->old_password
.response
.old_nt_hash_enc_data
) {
791 wbc_status
= WBC_ERR_INVALID_PARAM
;
792 BAIL_ON_WBC_ERROR(wbc_status
);
795 if (params
->new_password
.response
.lm_length
&&
796 !params
->new_password
.response
.lm_data
) {
797 wbc_status
= WBC_ERR_INVALID_PARAM
;
798 BAIL_ON_WBC_ERROR(wbc_status
);
801 if (params
->new_password
.response
.lm_length
== 0 &&
802 params
->new_password
.response
.lm_data
) {
803 wbc_status
= WBC_ERR_INVALID_PARAM
;
804 BAIL_ON_WBC_ERROR(wbc_status
);
807 if (params
->new_password
.response
.nt_length
&&
808 !params
->new_password
.response
.nt_data
) {
809 wbc_status
= WBC_ERR_INVALID_PARAM
;
810 BAIL_ON_WBC_ERROR(wbc_status
);
813 if (params
->new_password
.response
.nt_length
== 0 &&
814 params
->new_password
.response
.nt_data
) {
815 wbc_status
= WBC_ERR_INVALID_PARAM
;
816 BAIL_ON_WBC_ERROR(wbc_status
);
819 strncpy(request
.data
.chng_pswd_auth_crap
.user
,
820 params
->account_name
,
821 sizeof(request
.data
.chng_pswd_auth_crap
.user
) - 1);
823 strncpy(request
.data
.chng_pswd_auth_crap
.domain
,
825 sizeof(request
.data
.chng_pswd_auth_crap
.domain
) - 1);
827 if (params
->new_password
.response
.nt_data
) {
828 memcpy(request
.data
.chng_pswd_auth_crap
.new_nt_pswd
,
829 params
->new_password
.response
.nt_data
,
830 request
.data
.chng_pswd_auth_crap
.new_nt_pswd_len
);
831 request
.data
.chng_pswd_auth_crap
.new_nt_pswd_len
=
832 params
->new_password
.response
.nt_length
;
835 if (params
->new_password
.response
.lm_data
) {
836 memcpy(request
.data
.chng_pswd_auth_crap
.new_lm_pswd
,
837 params
->new_password
.response
.lm_data
,
838 request
.data
.chng_pswd_auth_crap
.new_lm_pswd_len
);
839 request
.data
.chng_pswd_auth_crap
.new_lm_pswd_len
=
840 params
->new_password
.response
.lm_length
;
843 if (params
->old_password
.response
.old_nt_hash_enc_data
) {
844 memcpy(request
.data
.chng_pswd_auth_crap
.old_nt_hash_enc
,
845 params
->old_password
.response
.old_nt_hash_enc_data
,
846 request
.data
.chng_pswd_auth_crap
.old_nt_hash_enc_len
);
847 request
.data
.chng_pswd_auth_crap
.old_nt_hash_enc_len
=
848 params
->old_password
.response
.old_nt_hash_enc_length
;
851 if (params
->old_password
.response
.old_lm_hash_enc_data
) {
852 memcpy(request
.data
.chng_pswd_auth_crap
.old_lm_hash_enc
,
853 params
->old_password
.response
.old_lm_hash_enc_data
,
854 request
.data
.chng_pswd_auth_crap
.old_lm_hash_enc_len
);
855 request
.data
.chng_pswd_auth_crap
.old_lm_hash_enc_len
=
856 params
->old_password
.response
.old_lm_hash_enc_length
;
861 wbc_status
= WBC_ERR_INVALID_PARAM
;
862 BAIL_ON_WBC_ERROR(wbc_status
);
867 wbc_status
= WBC_ERR_INVALID_PARAM
;
868 BAIL_ON_WBC_ERROR(wbc_status
);
873 wbc_status
= wbcRequestResponse(cmd
,
876 if (WBC_ERROR_IS_OK(wbc_status
)) {
880 /* Take the response above and return it to the caller */
882 if (response
.data
.auth
.nt_status
!= 0) {
884 wbc_status
= wbc_create_error_info(NULL
,
887 BAIL_ON_WBC_ERROR(wbc_status
);
893 wbc_status
= wbc_create_password_policy_info(NULL
,
896 BAIL_ON_WBC_ERROR(wbc_status
);
900 *reject_reason
= response
.data
.auth
.reject_reason
;
903 wbc_status
= WBC_ERR_PWD_CHANGE_FAILED
;
904 BAIL_ON_WBC_ERROR(wbc_status
);
910 /** @brief Change a password for a user
912 * @param username Name of user to authenticate
913 * @param old_password Old clear text password of user
914 * @param new_password New clear text password of user
919 wbcErr
wbcChangeUserPassword(const char *username
,
920 const char *old_password
,
921 const char *new_password
)
923 wbcErr wbc_status
= WBC_ERR_SUCCESS
;
924 struct wbcChangePasswordParams params
;
928 params
.account_name
= username
;
929 params
.level
= WBC_CHANGE_PASSWORD_LEVEL_PLAIN
;
930 params
.old_password
.plaintext
= old_password
;
931 params
.new_password
.plaintext
= new_password
;
933 wbc_status
= wbcChangeUserPasswordEx(¶ms
,
937 BAIL_ON_WBC_ERROR(wbc_status
);
943 /** @brief Logon a User
945 * @param[in] params Pointer to a wbcLogonUserParams structure
946 * @param[out] info Pointer to a pointer to a wbcLogonUserInfo structure
947 * @param[out] error Pointer to a pointer to a wbcAuthErrorInfo structure
948 * @param[out] policy Pointer to a pointer to a wbcUserPasswordPolicyInfo structure
954 wbcErr
wbcLogonUser(const struct wbcLogonUserParams
*params
,
955 struct wbcLogonUserInfo
**info
,
956 struct wbcAuthErrorInfo
**error
,
957 struct wbcUserPasswordPolicyInfo
**policy
)
959 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
961 struct winbindd_request request
;
962 struct winbindd_response response
;
965 ZERO_STRUCT(request
);
966 ZERO_STRUCT(response
);
979 wbc_status
= WBC_ERR_INVALID_PARAM
;
980 BAIL_ON_WBC_ERROR(wbc_status
);
983 if (!params
->username
) {
984 wbc_status
= WBC_ERR_INVALID_PARAM
;
985 BAIL_ON_WBC_ERROR(wbc_status
);
988 if ((params
->num_blobs
> 0) && (params
->blobs
== NULL
)) {
989 wbc_status
= WBC_ERR_INVALID_PARAM
;
990 BAIL_ON_WBC_ERROR(wbc_status
);
992 if ((params
->num_blobs
== 0) && (params
->blobs
!= NULL
)) {
993 wbc_status
= WBC_ERR_INVALID_PARAM
;
994 BAIL_ON_WBC_ERROR(wbc_status
);
997 /* Initialize request */
999 cmd
= WINBINDD_PAM_AUTH
;
1000 request
.flags
= WBFLAG_PAM_INFO3_TEXT
|
1001 WBFLAG_PAM_USER_SESSION_KEY
|
1004 if (!params
->password
) {
1005 wbc_status
= WBC_ERR_INVALID_PARAM
;
1006 BAIL_ON_WBC_ERROR(wbc_status
);
1009 strncpy(request
.data
.auth
.user
,
1011 sizeof(request
.data
.auth
.user
)-1);
1013 strncpy(request
.data
.auth
.pass
,
1015 sizeof(request
.data
.auth
.pass
)-1);
1017 for (i
=0; i
<params
->num_blobs
; i
++) {
1019 if (strcasecmp(params
->blobs
[i
].name
, "krb5_cc_type") == 0) {
1020 if (params
->blobs
[i
].blob
.data
) {
1021 strncpy(request
.data
.auth
.krb5_cc_type
,
1022 (const char *)params
->blobs
[i
].blob
.data
,
1023 sizeof(request
.data
.auth
.krb5_cc_type
) - 1);
1028 if (strcasecmp(params
->blobs
[i
].name
, "user_uid") == 0) {
1029 if (params
->blobs
[i
].blob
.data
) {
1030 memcpy(&request
.data
.auth
.uid
,
1031 params
->blobs
[i
].blob
.data
,
1032 MIN(sizeof(request
.data
.auth
.uid
),
1033 params
->blobs
[i
].blob
.length
));
1038 if (strcasecmp(params
->blobs
[i
].name
, "flags") == 0) {
1039 if (params
->blobs
[i
].blob
.data
) {
1042 params
->blobs
[i
].blob
.data
,
1044 params
->blobs
[i
].blob
.length
));
1045 request
.flags
|= flags
;
1050 if (strcasecmp(params
->blobs
[i
].name
, "membership_of") == 0) {
1051 if (params
->blobs
[i
].blob
.data
&&
1052 params
->blobs
[i
].blob
.data
[0] > 0) {
1053 strncpy(request
.data
.auth
.require_membership_of_sid
,
1054 (const char *)params
->blobs
[i
].blob
.data
,
1055 sizeof(request
.data
.auth
.require_membership_of_sid
) - 1);
1061 wbc_status
= wbcRequestResponse(cmd
,
1065 if (response
.data
.auth
.nt_status
!= 0) {
1067 wbc_status
= wbc_create_error_info(NULL
,
1070 BAIL_ON_WBC_ERROR(wbc_status
);
1073 wbc_status
= WBC_ERR_AUTH_ERROR
;
1074 BAIL_ON_WBC_ERROR(wbc_status
);
1076 BAIL_ON_WBC_ERROR(wbc_status
);
1079 wbc_status
= wbc_create_logon_info(NULL
,
1082 BAIL_ON_WBC_ERROR(wbc_status
);
1086 wbc_status
= wbc_create_password_policy_info(NULL
,
1089 BAIL_ON_WBC_ERROR(wbc_status
);
1093 if (response
.extra_data
.data
)
1094 free(response
.extra_data
.data
);
1099 /** @brief Authenticate a user with cached credentials
1101 * @param *params Pointer to a wbcCredentialCacheParams structure
1102 * @param **info Pointer to a pointer to a wbcCredentialCacheInfo structure
1103 * @param **error Pointer to a pointer to a wbcAuthErrorInfo structure
1107 wbcErr
wbcCredentialCache(struct wbcCredentialCacheParams
*params
,
1108 struct wbcCredentialCacheInfo
**info
,
1109 struct wbcAuthErrorInfo
**error
)
1111 return WBC_ERR_NOT_IMPLEMENTED
;