diff options
author | Karolin Seeger <kseeger@samba.org> | 2008-02-29 10:44:38 +0100 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2008-02-29 10:44:38 +0100 |
commit | c4fbe2846231a6b322c1094c6a1dbf93b7305768 (patch) | |
tree | 09eb77a294f4acda131b41fe4c9bec4ed175eb16 /source3/nsswitch | |
parent | 1a6415fc77c708b87c8e2ce6e7828f486ffc87ac (diff) | |
parent | 695b6662abe64a40061bfa05ede12173fc4b1945 (diff) | |
download | samba-c4fbe2846231a6b322c1094c6a1dbf93b7305768.tar.gz samba-c4fbe2846231a6b322c1094c6a1dbf93b7305768.tar.bz2 samba-c4fbe2846231a6b322c1094c6a1dbf93b7305768.zip |
Merge commit 'origin/v3-2-test' into v3-2-stable
Conflicts:
WHATSNEW.txt
(This used to be commit a390bcf9403df4cf4d5eef42b35ebccbe253882e)
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/libwbclient/wbc_pam.c | 375 | ||||
-rw-r--r-- | source3/nsswitch/libwbclient/wbc_pwd.c | 20 | ||||
-rw-r--r-- | source3/nsswitch/libwbclient/wbc_sid.c | 11 | ||||
-rw-r--r-- | source3/nsswitch/libwbclient/wbclient.c | 47 | ||||
-rw-r--r-- | source3/nsswitch/libwbclient/wbclient.h | 161 | ||||
-rw-r--r-- | source3/nsswitch/pam_winbind.c | 13 | ||||
-rw-r--r-- | source3/nsswitch/pam_winbind.h | 24 | ||||
-rw-r--r-- | source3/nsswitch/wb_common.c | 27 | ||||
-rw-r--r-- | source3/nsswitch/wbinfo.c | 392 | ||||
-rw-r--r-- | source3/nsswitch/winbind_client.h | 11 | ||||
-rw-r--r-- | source3/nsswitch/winbind_krb5_locator.c | 8 | ||||
-rw-r--r-- | source3/nsswitch/winbind_struct_protocol.h | 1 | ||||
-rw-r--r-- | source3/nsswitch/wins.c | 8 |
13 files changed, 814 insertions, 284 deletions
diff --git a/source3/nsswitch/libwbclient/wbc_pam.c b/source3/nsswitch/libwbclient/wbc_pam.c index 7f7c7b8140..1164ab173a 100644 --- a/source3/nsswitch/libwbclient/wbc_pam.c +++ b/source3/nsswitch/libwbclient/wbc_pam.c @@ -34,32 +34,389 @@ wbcErr wbcAuthenticateUser(const char *username, const char *password) { + wbcErr wbc_status = WBC_ERR_SUCCESS; + struct wbcAuthUserParams params; + + ZERO_STRUCT(params); + + params.account_name = username; + params.level = WBC_AUTH_USER_LEVEL_PLAIN; + params.password.plaintext = password; + + wbc_status = wbcAuthenticateUserEx(¶ms, NULL, NULL); + BAIL_ON_WBC_ERROR(wbc_status); + +done: + return wbc_status; +} + +static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx, + const struct winbindd_response *resp, + struct wbcAuthUserInfo **_i) +{ + wbcErr wbc_status = WBC_ERR_SUCCESS; + struct wbcAuthUserInfo *i; + struct wbcDomainSid domain_sid; + char *p; + uint32_t sn = 0; + uint32_t j; + + i = talloc(mem_ctx, struct wbcAuthUserInfo); + BAIL_ON_PTR_ERROR(i, wbc_status); + + i->user_flags = resp->data.auth.info3.user_flgs; + + i->account_name = talloc_strdup(i, resp->data.auth.info3.user_name); + BAIL_ON_PTR_ERROR(i->account_name, wbc_status); + i->user_principal= NULL; + i->full_name = talloc_strdup(i, resp->data.auth.info3.full_name); + BAIL_ON_PTR_ERROR(i->full_name, wbc_status); + i->domain_name = talloc_strdup(i, resp->data.auth.info3.logon_dom); + BAIL_ON_PTR_ERROR(i->domain_name, wbc_status); + i->dns_domain_name= NULL; + + i->acct_flags = resp->data.auth.info3.acct_flags; + memcpy(i->user_session_key, + resp->data.auth.user_session_key, + sizeof(i->user_session_key)); + memcpy(i->lm_session_key, + resp->data.auth.first_8_lm_hash, + sizeof(i->lm_session_key)); + + i->logon_count = resp->data.auth.info3.logon_count; + i->bad_password_count = resp->data.auth.info3.bad_pw_count; + + i->logon_time = resp->data.auth.info3.logon_time; + i->logoff_time = resp->data.auth.info3.logoff_time; + i->kickoff_time = resp->data.auth.info3.kickoff_time; + i->pass_last_set_time = resp->data.auth.info3.pass_last_set_time; + i->pass_can_change_time = resp->data.auth.info3.pass_can_change_time; + i->pass_must_change_time= resp->data.auth.info3.pass_must_change_time; + + i->logon_server = talloc_strdup(i, resp->data.auth.info3.logon_srv); + BAIL_ON_PTR_ERROR(i->logon_server, wbc_status); + i->logon_script = talloc_strdup(i, resp->data.auth.info3.logon_script); + BAIL_ON_PTR_ERROR(i->logon_script, wbc_status); + i->profile_path = talloc_strdup(i, resp->data.auth.info3.profile_path); + BAIL_ON_PTR_ERROR(i->profile_path, wbc_status); + i->home_directory= talloc_strdup(i, resp->data.auth.info3.home_dir); + BAIL_ON_PTR_ERROR(i->home_directory, wbc_status); + i->home_drive = talloc_strdup(i, resp->data.auth.info3.dir_drive); + BAIL_ON_PTR_ERROR(i->home_drive, wbc_status); + + i->num_sids = 2; + i->num_sids += resp->data.auth.info3.num_groups; + i->num_sids += resp->data.auth.info3.num_other_sids; + + i->sids = talloc_array(i, struct wbcSidWithAttr, i->num_sids); + BAIL_ON_PTR_ERROR(i->sids, wbc_status); + + wbc_status = wbcStringToSid(resp->data.auth.info3.dom_sid, + &domain_sid); + BAIL_ON_WBC_ERROR(wbc_status); + +#define _SID_COMPOSE(s, d, r, a) { \ + (s).sid = d; \ + if ((s).sid.num_auths < MAXSUBAUTHS) { \ + (s).sid.sub_auths[(s).sid.num_auths++] = r; \ + } else { \ + wbc_status = WBC_ERR_INVALID_SID; \ + BAIL_ON_WBC_ERROR(wbc_status); \ + } \ + (s).attributes = a; \ +} while (0) + + sn = 0; + _SID_COMPOSE(i->sids[sn], domain_sid, + resp->data.auth.info3.user_rid, + 0); + sn++; + _SID_COMPOSE(i->sids[sn], domain_sid, + resp->data.auth.info3.group_rid, + 0); + sn++; + + p = (char *)resp->extra_data.data; + if (!p) { + wbc_status = WBC_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + + for (j=0; j < resp->data.auth.info3.num_groups; j++) { + uint32_t rid; + uint32_t attrs; + int ret; + char *s = p; + char *e = strchr(p, '\n'); + if (!e) { + wbc_status = WBC_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + e[0] = '\0'; + p = &e[1]; + + ret = sscanf(s, "0x%08X:0x%08X", &rid, &attrs); + if (ret != 2) { + wbc_status = WBC_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + + _SID_COMPOSE(i->sids[sn], domain_sid, + rid, attrs); + sn++; + } + + for (j=0; j < resp->data.auth.info3.num_other_sids; j++) { + uint32_t attrs; + int ret; + char *s = p; + char *a; + char *e = strchr(p, '\n'); + if (!e) { + wbc_status = WBC_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + e[0] = '\0'; + p = &e[1]; + + e = strchr(s, ':'); + if (!e) { + wbc_status = WBC_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + e[0] = '\0'; + a = &e[1]; + + ret = sscanf(a, "0x%08X", + &attrs); + if (ret != 1) { + wbc_status = WBC_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + + wbc_status = wbcStringToSid(s, &i->sids[sn].sid); + BAIL_ON_WBC_ERROR(wbc_status); + + i->sids[sn].attributes = attrs; + sn++; + } + + i->num_sids = sn; + + *_i = i; + i = NULL; +done: + talloc_free(i); + return wbc_status; +} + +static wbcErr wbc_create_error_info(TALLOC_CTX *mem_ctx, + const struct winbindd_response *resp, + struct wbcAuthErrorInfo **_e) +{ + wbcErr wbc_status = WBC_ERR_SUCCESS; + struct wbcAuthErrorInfo *e; + + e = talloc(mem_ctx, struct wbcAuthErrorInfo); + BAIL_ON_PTR_ERROR(e, wbc_status); + + e->nt_status = resp->data.auth.nt_status; + e->pam_error = resp->data.auth.pam_error; + e->nt_string = talloc_strdup(e, resp->data.auth.nt_status_string); + BAIL_ON_PTR_ERROR(e->nt_string, wbc_status); + + e->display_string = talloc_strdup(e, resp->data.auth.error_string); + BAIL_ON_PTR_ERROR(e->display_string, wbc_status); + + *_e = e; + e = NULL; + +done: + talloc_free(e); + return wbc_status; +} + +/** @brief Authenticate with more detailed information + * + * @param params Input parameters, WBC_AUTH_USER_LEVEL_HASH + * is not supported yet + * @param info Output details on WBC_ERR_SUCCESS + * @param error Output details on WBC_ERR_AUTH_ERROR + * + * @return #wbcErr + **/ + +wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params, + struct wbcAuthUserInfo **info, + struct wbcAuthErrorInfo **error) +{ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + int cmd = 0; struct winbindd_request request; struct winbindd_response response; - if (!username) { + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + if (error) { + *error = NULL; + } + + if (!params) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + if (!params->account_name) { wbc_status = WBC_ERR_INVALID_PARAM; BAIL_ON_WBC_ERROR(wbc_status); } /* Initialize request */ - ZERO_STRUCT(request); - ZERO_STRUCT(response); + switch (params->level) { + case WBC_AUTH_USER_LEVEL_PLAIN: + cmd = WINBINDD_PAM_AUTH; + request.flags = WBFLAG_PAM_INFO3_TEXT | + WBFLAG_PAM_USER_SESSION_KEY | + WBFLAG_PAM_LMKEY; + + if (!params->password.plaintext) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + if (params->domain_name && params->domain_name[0]) { + /* We need to get the winbind separator :-( */ + struct winbindd_response sep_response; - /* dst is already null terminated from the memset above */ + ZERO_STRUCT(sep_response); - strncpy(request.data.auth.user, username, - sizeof(request.data.auth.user)-1); - strncpy(request.data.auth.pass, password, - sizeof(request.data.auth.user)-1); + wbc_status = wbcRequestResponse(WINBINDD_INFO, + NULL, &sep_response); + BAIL_ON_WBC_ERROR(wbc_status); - wbc_status = wbcRequestResponse(WINBINDD_PAM_AUTH, + snprintf(request.data.auth.user, + sizeof(request.data.auth.user)-1, + "%s%c%s", + params->domain_name, + sep_response.data.info.winbind_separator, + params->account_name); + } else { + strncpy(request.data.auth.user, + params->account_name, + sizeof(request.data.auth.user)-1); + } + strncpy(request.data.auth.pass, + params->password.plaintext, + sizeof(request.data.auth.user)-1); + break; + + case WBC_AUTH_USER_LEVEL_HASH: + wbc_status = WBC_ERR_NOT_IMPLEMENTED; + BAIL_ON_WBC_ERROR(wbc_status); + break; + + case WBC_AUTH_USER_LEVEL_RESPONSE: + cmd = WINBINDD_PAM_AUTH_CRAP; + request.flags = WBFLAG_PAM_INFO3_TEXT | + WBFLAG_PAM_USER_SESSION_KEY | + WBFLAG_PAM_LMKEY; + + if (params->password.response.lm_length && + params->password.response.lm_data) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + if (params->password.response.lm_length == 0 && + params->password.response.lm_data) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + if (params->password.response.nt_length && + !params->password.response.nt_data) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + if (params->password.response.nt_length == 0&& + params->password.response.nt_data) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + strncpy(request.data.auth_crap.user, + params->account_name, + sizeof(request.data.auth_crap.user)-1); + if (params->domain_name) { + strncpy(request.data.auth_crap.domain, + params->domain_name, + sizeof(request.data.auth_crap.domain)-1); + } + if (params->workstation_name) { + strncpy(request.data.auth_crap.workstation, + params->workstation_name, + sizeof(request.data.auth_crap.workstation)-1); + } + + request.data.auth_crap.logon_parameters = + params->parameter_control; + + memcpy(request.data.auth_crap.chal, + params->password.response.challenge, + sizeof(request.data.auth_crap.chal)); + + request.data.auth_crap.lm_resp_len = + MIN(params->password.response.lm_length, + sizeof(request.data.auth_crap.lm_resp)); + request.data.auth_crap.nt_resp_len = + MIN(params->password.response.nt_length, + sizeof(request.data.auth_crap.nt_resp)); + if (params->password.response.lm_data) { + memcpy(request.data.auth_crap.lm_resp, + params->password.response.lm_data, + request.data.auth_crap.lm_resp_len); + } + if (params->password.response.nt_data) { + memcpy(request.data.auth_crap.nt_resp, + params->password.response.nt_data, + request.data.auth_crap.nt_resp_len); + } + break; + default: + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + if (cmd == 0) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + wbc_status = wbcRequestResponse(cmd, &request, &response); + if (response.data.auth.nt_status != 0) { + if (error) { + wbc_status = wbc_create_error_info(NULL, + &response, + error); + BAIL_ON_WBC_ERROR(wbc_status); + } + + wbc_status = WBC_ERR_AUTH_ERROR; + BAIL_ON_WBC_ERROR(wbc_status); + } BAIL_ON_WBC_ERROR(wbc_status); + if (info) { + wbc_status = wbc_create_auth_info(NULL, + &response, + info); + BAIL_ON_WBC_ERROR(wbc_status); + } + done: + return wbc_status; } diff --git a/source3/nsswitch/libwbclient/wbc_pwd.c b/source3/nsswitch/libwbclient/wbc_pwd.c index b24e198bc5..b7febcce0c 100644 --- a/source3/nsswitch/libwbclient/wbc_pwd.c +++ b/source3/nsswitch/libwbclient/wbc_pwd.c @@ -209,16 +209,16 @@ wbcErr wbcGetgrnam(const char *name, struct group **grp) struct winbindd_request request; struct winbindd_response response; - if (!name || !grp) { - wbc_status = WBC_ERR_INVALID_PARAM; - BAIL_ON_WBC_ERROR(wbc_status); - } - /* Initialize request */ ZERO_STRUCT(request); ZERO_STRUCT(response); + if (!name || !grp) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + /* dst is already null terminated from the memset above */ strncpy(request.data.groupname, name, sizeof(request.data.groupname)-1); @@ -254,16 +254,16 @@ wbcErr wbcGetgrgid(gid_t gid, struct group **grp) struct winbindd_request request; struct winbindd_response response; - if (!grp) { - wbc_status = WBC_ERR_INVALID_PARAM; - BAIL_ON_WBC_ERROR(wbc_status); - } - /* Initialize request */ ZERO_STRUCT(request); ZERO_STRUCT(response); + if (!grp) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + request.data.gid = gid; wbc_status = wbcRequestResponse(WINBINDD_GETGRGID, diff --git a/source3/nsswitch/libwbclient/wbc_sid.c b/source3/nsswitch/libwbclient/wbc_sid.c index abe1457cc1..0519d8bf9f 100644 --- a/source3/nsswitch/libwbclient/wbc_sid.c +++ b/source3/nsswitch/libwbclient/wbc_sid.c @@ -311,16 +311,16 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, char *domain_name = NULL; wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; - if (!dom_sid || (num_rids == 0)) { - wbc_status = WBC_ERR_INVALID_PARAM; - BAIL_ON_WBC_ERROR(wbc_status); - } - /* Initialise request */ ZERO_STRUCT(request); ZERO_STRUCT(response); + if (!dom_sid || (num_rids == 0)) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + wbc_status = wbcSidToString(dom_sid, &sid_string); BAIL_ON_WBC_ERROR(wbc_status); @@ -355,6 +355,7 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, &request, &response); talloc_free(ridlist); + BAIL_ON_WBC_ERROR(wbc_status); domain_name = talloc_strdup(NULL, response.data.domain_name); BAIL_ON_PTR_ERROR(domain_name, wbc_status); diff --git a/source3/nsswitch/libwbclient/wbclient.c b/source3/nsswitch/libwbclient/wbclient.c index 321a7db669..e17296283f 100644 --- a/source3/nsswitch/libwbclient/wbclient.c +++ b/source3/nsswitch/libwbclient/wbclient.c @@ -59,11 +59,7 @@ wbcErr wbcRequestResponse(int cmd, wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; NSS_STATUS nss_status; - if (!request || !response) { - wbc_status = WBC_ERR_INVALID_PARAM; - BAIL_ON_WBC_ERROR(wbc_status); - } - + /* for some calls the request and/or response cna be NULL */ nss_status = winbindd_request_response(cmd, request, response); @@ -72,20 +68,55 @@ wbcErr wbcRequestResponse(int cmd, wbc_status = WBC_ERR_SUCCESS; break; case NSS_STATUS_UNAVAIL: - return WBC_ERR_WINBIND_NOT_AVAILABLE; + wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE; break; case NSS_STATUS_NOTFOUND: - return WBC_ERR_DOMAIN_NOT_FOUND; + wbc_status = WBC_ERR_DOMAIN_NOT_FOUND; break; default: wbc_status = WBC_ERR_NSS_ERROR; break; } -done: return wbc_status; } +/** @brief Translate an error value into a string + * + * @param error + * + * @return a pointer to a static string + **/ +const char *wbcErrorString(wbcErr error) +{ + switch (error) { + case WBC_ERR_SUCCESS: + return "WBC_ERR_SUCCESS"; + case WBC_ERR_NOT_IMPLEMENTED: + return "WBC_ERR_NOT_IMPLEMENTED"; + case WBC_ERR_UNKNOWN_FAILURE: + return "WBC_ERR_UNKNOWN_FAILURE"; + case WBC_ERR_NO_MEMORY: + return "WBC_ERR_NO_MEMORY"; + case WBC_ERR_INVALID_SID: + return "WBC_ERR_INVALID_SID"; + case WBC_ERR_INVALID_PARAM: + return "WBC_ERR_INVALID_PARAM"; + case WBC_ERR_WINBIND_NOT_AVAILABLE: + return "WBC_ERR_WINBIND_NOT_AVAILABLE"; + case WBC_ERR_DOMAIN_NOT_FOUND: + return "WBC_ERR_DOMAIN_NOT_FOUND"; + case WBC_INVALID_RESPONSE: + return "WBC_INVALID_RESPONSE"; + case WBC_ERR_NSS_ERROR: + return "WBC_ERR_NSS_ERROR"; + case WBC_ERR_AUTH_ERROR: + return "WBC_ERR_AUTH_ERROR"; + } + + return "unknown wbcErr value"; +}; + /** @brief Free library allocated memory * * @param *p Pointer to free diff --git a/source3/nsswitch/libwbclient/wbclient.h b/source3/nsswitch/libwbclient/wbclient.h index 0b256d343f..c01db9618d 100644 --- a/source3/nsswitch/libwbclient/wbclient.h +++ b/source3/nsswitch/libwbclient/wbclient.h @@ -41,14 +41,15 @@ enum _wbcErrType { WBC_ERR_WINBIND_NOT_AVAILABLE, /**< Winbind daemon is not available **/ WBC_ERR_DOMAIN_NOT_FOUND, /**< Domain is not trusted or cannot be found **/ WBC_INVALID_RESPONSE, /**< Winbind returned an invalid response **/ - WBC_ERR_NSS_ERROR /**< NSS_STATUS error **/ + WBC_ERR_NSS_ERROR, /**< NSS_STATUS error **/ + WBC_ERR_AUTH_ERROR /**< Authentication failed **/ }; typedef enum _wbcErrType wbcErr; #define WBC_ERROR_IS_OK(x) ((x) == WBC_ERR_SUCCESS) -char *wbcErrorString(wbcErr error); +const char *wbcErrorString(wbcErr error); /* * Data types used by the Winbind Client API @@ -88,6 +89,25 @@ enum wbcSidType { }; /** + * @brief Security Identifier with attributes + **/ + +struct wbcSidWithAttr { + struct wbcDomainSid sid; + uint32_t attributes; +}; + +/* wbcSidWithAttr->attributes */ + +#define WBC_SID_ATTR_GROUP_MANDATORY 0x00000001 +#define WBC_SID_ATTR_GROUP_ENABLED_BY_DEFAULT 0x00000002 +#define WBC_SID_ATTR_GROUP_ENABLED 0x00000004 +#define WBC_SID_ATTR_GROUP_OWNER 0x00000008 +#define WBC_SID_ATTR_GROUP_USEFOR_DENY_ONLY 0x00000010 +#define WBC_SID_ATTR_GROUP_RESOURCE 0x20000000 +#define WBC_SID_ATTR_GROUP_LOGON_ID 0xC0000000 + +/** * @brief Domain Information **/ @@ -104,6 +124,140 @@ struct wbcDomainInfo { #define WBC_DOMINFO_AD 0x00000002 #define WBC_DOMINFO_PRIMARY 0x00000004 +/** + * @brief Auth User Parameters + **/ + +struct wbcAuthUserParams { + const char *account_name; + const char *domain_name; + const char *workstation_name; + + uint32_t flags; + + uint32_t parameter_control; + + enum wbcAuthUserLevel { + WBC_AUTH_USER_LEVEL_PLAIN = 1, + WBC_AUTH_USER_LEVEL_HASH = 2, + WBC_AUTH_USER_LEVEL_RESPONSE = 3 + } level; + union { + const char *plaintext; + struct { + uint8_t nt_hash[16]; + uint8_t lm_hash[16]; + } hash; + struct { + uint8_t challenge[8]; + uint32_t nt_length; + uint8_t *nt_data; + uint32_t lm_length; + uint8_t *lm_data; + } response; + } password; +}; + +/* wbcAuthUserParams->parameter_control */ + +#define WBC_MSV1_0_CLEARTEXT_PASSWORD_ALLOWED 0x00000002 +#define WBC_MSV1_0_UPDATE_LOGON_STATISTICS 0x00000004 +#define WBC_MSV1_0_RETURN_USER_PARAMETERS 0x00000008 +#define WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT 0x00000020 +#define WBC_MSV1_0_RETURN_PROFILE_PATH 0x00000200 +#define WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT 0x00000800 + +/* wbcAuthUserParams->flags */ + +#define WBC_AUTH_PARAM_FLAGS_INTERACTIVE_LOGON 0x00000001 + +/** + * @brief Auth User Information + * + * Some of the strings are maybe NULL + **/ + +struct wbcAuthUserInfo { + uint32_t user_flags; + + char *account_name; + char *user_principal; + char *full_name; + char *domain_name; + char *dns_domain_name; + + uint32_t acct_flags; + uint8_t user_session_key[16]; + uint8_t lm_session_key[8]; + + uint16_t logon_count; + uint16_t bad_password_count; + + uint64_t logon_time; + uint64_t logoff_time; + uint64_t kickoff_time; + uint64_t pass_last_set_time; + uint64_t pass_can_change_time; + uint64_t pass_must_change_time; + + char *logon_server; + char *logon_script; + char *profile_path; + char *home_directory; + char *home_drive; + + /* + * the 1st one is the account sid + * the 2nd one is the primary_group sid + * followed by the rest of the groups + */ + uint32_t num_sids; + struct wbcSidWithAttr *sids; +}; + +/* wbcAuthUserInfo->user_flags */ + +#define WBC_AUTH_USER_INFO_GUEST 0x00000001 +#define WBC_AUTH_USER_INFO_NOENCRYPTION 0x00000002 +#define WBC_AUTH_USER_INFO_CACHED_ACCOUNT 0x00000004 +#define WBC_AUTH_USER_INFO_USED_LM_PASSWORD 0x00000008 +#define WBC_AUTH_USER_INFO_EXTRA_SIDS 0x00000020 +#define WBC_AUTH_USER_INFO_SUBAUTH_SESSION_KEY 0x00000040 +#define WBC_AUTH_USER_INFO_SERVER_TRUST_ACCOUNT 0x00000080 +#define WBC_AUTH_USER_INFO_NTLMV2_ENABLED 0x00000100 +#define WBC_AUTH_USER_INFO_RESOURCE_GROUPS 0x00000200 +#define WBC_AUTH_USER_INFO_PROFILE_PATH_RETURNED 0x00000400 +#define WBC_AUTH_USER_INFO_GRACE_LOGON 0x01000000 + +/* wbcAuthUserInfo->acct_flags */ + +#define WBC_ACB_DISABLED 0x00000001 /* 1 User account disabled */ +#define WBC_ACB_HOMDIRREQ 0x00000002 /* 1 Home directory required */ +#define WBC_ACB_PWNOTREQ 0x00000004 /* 1 User password not required */ +#define WBC_ACB_TEMPDUP 0x00000008 /* 1 Temporary duplicate account */ +#define WBC_ACB_NORMAL 0x00000010 /* 1 Normal user account */ +#define WBC_ACB_MNS 0x00000020 /* 1 MNS logon user account */ +#define WBC_ACB_DOMTRUST 0x00000040 /* 1 Interdomain trust account */ +#define WBC_ACB_WSTRUST 0x00000080 /* 1 Workstation trust account */ +#define WBC_ACB_SVRTRUST 0x00000100 /* 1 Server trust account */ +#define WBC_ACB_PWNOEXP 0x00000200 /* 1 User password does not expire */ +#define WBC_ACB_AUTOLOCK 0x00000400 /* 1 Account auto locked */ +#define WBC_ACB_ENC_TXT_PWD_ALLOWED 0x00000800 /* 1 Encryped text password is allowed */ +#define WBC_ACB_SMARTCARD_REQUIRED 0x00001000 /* 1 Smart Card required */ +#define WBC_ACB_TRUSTED_FOR_DELEGATION 0x00002000 /* 1 Trusted for Delegation */ +#define WBC_ACB_NOT_DELEGATED 0x00004000 /* 1 Not delegated */ +#define WBC_ACB_USE_DES_KEY_ONLY 0x00008000 /* 1 Use DES key only */ +#define WBC_ACB_DONT_REQUIRE_PREAUTH 0x00010000 /* 1 Preauth not required */ +#define WBC_ACB_PW_EXPIRED 0x00020000 /* 1 Password Expired */ +#define WBC_ACB_NO_AUTH_DATA_REQD 0x00080000 /* 1 = No authorization data required */ + +struct wbcAuthErrorInfo { + uint32_t nt_status; + char *nt_string; + int32_t pam_error; + char *display_string; +}; + /* * Memory Management */ @@ -205,5 +359,8 @@ wbcErr wbcDomainSequenceNumbers(void); wbcErr wbcAuthenticateUser(const char *username, const char *password); +wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params, + struct wbcAuthUserInfo **info, + struct wbcAuthErrorInfo **error); #endif /* _WBCLIENT_H */ diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c index 4d019072ac..81f5227410 100644 --- a/source3/nsswitch/pam_winbind.c +++ b/source3/nsswitch/pam_winbind.c @@ -1341,9 +1341,10 @@ static int winbind_auth_request(pam_handle_t * pamh, /* If winbindd returned a username, return the pointer to it * here. */ - if (user_ret && response.extra_data.data) { + if (user_ret && response.data.auth.unix_username[0]) { /* We have to trust it's a null terminated string. */ - *user_ret = (char *)response.extra_data.data; + *user_ret = strndup(response.data.auth.unix_username, + sizeof(response.data.auth.unix_username) - 1); } } @@ -1431,22 +1432,22 @@ static int winbind_chauthtok_request(pam_handle_t * pamh, switch (reject_reason) { case -1: break; - case REJECT_REASON_OTHER: + case SAMR_REJECT_OTHER: if ((min_pwd_age > 0) && (pwd_last_set + min_pwd_age > time(NULL))) { PAM_WB_REMARK_DIRECT(pamh, ctrl, "NT_STATUS_PWD_TOO_RECENT"); } break; - case REJECT_REASON_TOO_SHORT: + case SAMR_REJECT_TOO_SHORT: PAM_WB_REMARK_DIRECT(pamh, ctrl, "NT_STATUS_PWD_TOO_SHORT"); break; - case REJECT_REASON_IN_HISTORY: + case SAMR_REJECT_IN_HISTORY: PAM_WB_REMARK_DIRECT(pamh, ctrl, "NT_STATUS_PWD_HISTORY_CONFLICT"); break; - case REJECT_REASON_NOT_COMPLEX: + case SAMR_REJECT_COMPLEXITY: _make_remark(pamh, ctrl, PAM_ERROR_MSG, "Password does not meet " "complexity requirements"); diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h index 59a2f39584..a1d32726f5 100644 --- a/source3/nsswitch/pam_winbind.h +++ b/source3/nsswitch/pam_winbind.h @@ -12,6 +12,7 @@ #define PAM_SM_AUTH #define PAM_SM_ACCOUNT #define PAM_SM_PASSWORD +#define PAM_SM_SESSION #ifndef PAM_WINBIND_CONFIG_FILE #define PAM_WINBIND_CONFIG_FILE "/etc/security/pam_winbind.conf" @@ -179,22 +180,23 @@ do { \ };\ }; -/* from include/rpc_samr.h */ -#define DOMAIN_PASSWORD_COMPLEX 0x00000001 +/* from samr.idl */ +#define DOMAIN_PASSWORD_COMPLEX 0x00000001 -#define REJECT_REASON_OTHER 0x00000000 -#define REJECT_REASON_TOO_SHORT 0x00000001 -#define REJECT_REASON_IN_HISTORY 0x00000002 -#define REJECT_REASON_NOT_COMPLEX 0x00000005 +#define SAMR_REJECT_OTHER 0x00000000 +#define SAMR_REJECT_TOO_SHORT 0x00000001 +#define SAMR_REJECT_IN_HISTORY 0x00000002 +#define SAMR_REJECT_COMPLEXITY 0x00000005 -/* from include/smb.h */ #define ACB_PWNOEXP 0x00000200 +/* from netlogon.idl */ +#define NETLOGON_CACHED_ACCOUNT 0x00000004 +#define NETLOGON_GRACE_LOGON 0x01000000 + /* from include/rpc_netlogon.h */ -#define LOGON_CACHED_ACCOUNT 0x00000004 -#define LOGON_GRACE_LOGON 0x01000000 #define LOGON_KRB5_FAIL_CLOCK_SKEW 0x02000000 -#define PAM_WB_CACHED_LOGON(x) (x & LOGON_CACHED_ACCOUNT) +#define PAM_WB_CACHED_LOGON(x) (x & NETLOGON_CACHED_ACCOUNT) #define PAM_WB_KRB5_CLOCK_SKEW(x) (x & LOGON_KRB5_FAIL_CLOCK_SKEW) -#define PAM_WB_GRACE_LOGON(x) ((LOGON_CACHED_ACCOUNT|LOGON_GRACE_LOGON) == ( x & (LOGON_CACHED_ACCOUNT|LOGON_GRACE_LOGON))) +#define PAM_WB_GRACE_LOGON(x) ((NETLOGON_CACHED_ACCOUNT|NETLOGON_GRACE_LOGON) == ( x & (NETLOGON_CACHED_ACCOUNT|NETLOGON_GRACE_LOGON))) diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c index 49a2935bff..b113fc3336 100644 --- a/source3/nsswitch/wb_common.c +++ b/source3/nsswitch/wb_common.c @@ -538,18 +538,6 @@ int winbindd_read_reply(struct winbindd_response *response) return result1 + result2; } -bool winbind_env_set(void) -{ - char *env; - - if ((env=getenv(WINBINDD_DONT_ENV)) != NULL) { - if(strcmp(env, "1") == 0) { - return true; - } - } - return false; -} - /* * send simple types of requests */ @@ -663,21 +651,6 @@ NSS_STATUS winbindd_priv_request_response(int req_type, } /************************************************************************* - A couple of simple functions to disable winbindd lookups and re- - enable them - ************************************************************************/ - -bool winbind_off(void) -{ - return setenv(WINBINDD_DONT_ENV, "1", 1) != -1; -} - -bool winbind_on(void) -{ - return setenv(WINBINDD_DONT_ENV, "0", 1) != -1; -} - -/************************************************************************* ************************************************************************/ const char *nss_err_str(NSS_STATUS ret) diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index c8f8398c6f..ee51cce835 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -53,7 +53,7 @@ static char winbind_separator_int(bool strict) } sep = response.data.info.winbind_separator; - got_sep = True; + got_sep = true; if (!sep) { d_fprintf(stderr, "winbind separator was NULL!\n"); @@ -69,27 +69,27 @@ static char winbind_separator_int(bool strict) static char winbind_separator(void) { - return winbind_separator_int(False); + return winbind_separator_int(false); } static const char *get_winbind_domain(void) { - wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainInfo *dinfo = NULL; static fstring winbind_domain; ZERO_STRUCT(dinfo); - + wbc_status = wbcDomainInfo(".", &dinfo); if (!WBC_ERROR_IS_OK(wbc_status)) { d_fprintf(stderr, "could not obtain winbind domain name!\n"); - + /* HACK: (this module should not call lp_ funtions) */ return lp_workgroup(); } - fstrcpy(winbind_domain, dinfo->short_name); + fstrcpy(winbind_domain, dinfo->short_name); wbcFreeMemory(dinfo); @@ -99,7 +99,7 @@ static const char *get_winbind_domain(void) /* Copy of parse_domain_user from winbindd_util.c. Parse a string of the form DOMAIN/user into a domain and a user */ -static bool parse_wbinfo_domain_user(const char *domuser, fstring domain, +static bool parse_wbinfo_domain_user(const char *domuser, fstring domain, fstring user) { @@ -110,20 +110,20 @@ static bool parse_wbinfo_domain_user(const char *domuser, fstring domain, if ((p = strchr(domuser, '@')) != NULL) { fstrcpy(domain, ""); fstrcpy(user, domuser); - return True; + return true; } - + fstrcpy(user, domuser); fstrcpy(domain, get_winbind_domain()); - return True; + return true; } - + fstrcpy(user, p+1); fstrcpy(domain, domuser); domain[PTR_DIFF(p, domuser)] = 0; strupper_m(domain); - return True; + return true; } /* pull pwent info for a given user */ @@ -131,13 +131,13 @@ static bool parse_wbinfo_domain_user(const char *domuser, fstring domain, static bool wbinfo_get_userinfo(char *user) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; - struct passwd *pwd = NULL; + struct passwd *pwd = NULL; wbc_status = wbcGetpwnam(user, &pwd); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } - + d_printf("%s:%s:%d:%d:%s:%s:%s\n", pwd->pw_name, pwd->pw_passwd, @@ -146,7 +146,7 @@ static bool wbinfo_get_userinfo(char *user) pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); - + return true; } @@ -154,13 +154,13 @@ static bool wbinfo_get_userinfo(char *user) static bool wbinfo_get_uidinfo(int uid) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; - struct passwd *pwd = NULL; + struct passwd *pwd = NULL; wbc_status = wbcGetpwuid(uid, &pwd); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } - + d_printf("%s:%s:%d:%d:%s:%s:%s\n", pwd->pw_name, pwd->pw_passwd, @@ -169,7 +169,7 @@ static bool wbinfo_get_uidinfo(int uid) pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); - + return true; } @@ -191,14 +191,14 @@ static bool wbinfo_get_groupinfo(char *group) &response); if ( result != NSS_STATUS_SUCCESS) - return False; + return false; - d_printf( "%s:%s:%d\n", + d_printf( "%s:%s:%d\n", response.data.gr.gr_name, response.data.gr.gr_passwd, response.data.gr.gr_gid ); - - return True; + + return true; } /* List groups a user is a member of */ @@ -209,7 +209,7 @@ static bool wbinfo_get_usergroups(char *user) struct winbindd_response response; NSS_STATUS result; int i; - + ZERO_STRUCT(request); ZERO_STRUCT(response); @@ -220,14 +220,14 @@ static bool wbinfo_get_usergroups(char *user) result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); if (result != NSS_STATUS_SUCCESS) - return False; + return false; for (i = 0; i < response.data.num_entries; i++) d_printf("%d\n", (int)((gid_t *)response.extra_data.data)[i]); SAFE_FREE(response.extra_data.data); - return True; + return true; } @@ -249,7 +249,7 @@ static bool wbinfo_get_usersids(char *user_sid) result = winbindd_request_response(WINBINDD_GETUSERSIDS, &request, &response); if (result != NSS_STATUS_SUCCESS) - return False; + return false; s = (const char *)response.extra_data.data; for (i = 0; i < response.data.num_entries; i++) { @@ -259,7 +259,7 @@ static bool wbinfo_get_usersids(char *user_sid) SAFE_FREE(response.extra_data.data); - return True; + return true; } static bool wbinfo_get_userdomgroups(const char *user_sid) @@ -275,17 +275,17 @@ static bool wbinfo_get_userdomgroups(const char *user_sid) fstrcpy(request.data.sid, user_sid); result = winbindd_request_response(WINBINDD_GETUSERDOMGROUPS, &request, - &response); + &response); if (result != NSS_STATUS_SUCCESS) - return False; + return false; if (response.data.num_entries != 0) printf("%s", (char *)response.extra_data.data); - + SAFE_FREE(response.extra_data.data); - return True; + return true; } /* Convert NetBIOS name to IP */ @@ -304,14 +304,14 @@ static bool wbinfo_wins_byname(char *name) if (winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response) != NSS_STATUS_SUCCESS) { - return False; + return false; } /* Display response */ d_printf("%s\n", response.data.winsresp); - return True; + return true; } /* Convert IP to NetBIOS name */ @@ -330,14 +330,14 @@ static bool wbinfo_wins_byip(char *ip) if (winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response) != NSS_STATUS_SUCCESS) { - return False; + return false; } /* Display response */ d_printf("%s\n", response.data.winsresp); - return True; + return true; } /* List trusted domains */ @@ -356,7 +356,7 @@ static bool wbinfo_list_domains(bool list_all_domains) if (winbindd_request_response(WINBINDD_LIST_TRUSTDOM, &request, &response) != NSS_STATUS_SUCCESS) - return False; + return false; /* Display response */ @@ -373,7 +373,7 @@ static bool wbinfo_list_domains(bool list_all_domains) extra_data); TALLOC_FREE(frame); SAFE_FREE(response.extra_data.data); - return False; + return false; } *p = 0; d_printf("%s\n", name); @@ -382,7 +382,7 @@ static bool wbinfo_list_domains(bool list_all_domains) SAFE_FREE(response.extra_data.data); } - return True; + return true; } /* List own domain */ @@ -391,7 +391,7 @@ static bool wbinfo_list_own_domain(void) { d_printf("%s\n", get_winbind_domain()); - return True; + return true; } /* show sequence numbers */ @@ -410,7 +410,7 @@ static bool wbinfo_show_sequence(const char *domain) if (winbindd_request_response(WINBINDD_SHOW_SEQUENCE, &request, &response) != NSS_STATUS_SUCCESS) - return False; + return false; /* Display response */ @@ -427,7 +427,7 @@ static bool wbinfo_show_sequence(const char *domain) SAFE_FREE(response.extra_data.data); } - return True; + return true; } /* Show domain info */ @@ -449,7 +449,7 @@ static bool wbinfo_domain_info(const char *domain_name) if (winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response) != NSS_STATUS_SUCCESS) - return False; + return false; /* Display response */ @@ -466,7 +466,7 @@ static bool wbinfo_domain_info(const char *domain_name) d_printf("Primary : %s\n", response.data.domain_info.primary ? "Yes" : "No"); - return True; + return true; } /* Get a foreign DC's name */ @@ -485,14 +485,14 @@ static bool wbinfo_getdcname(const char *domain_name) if (winbindd_request_response(WINBINDD_GETDCNAME, &request, &response) != NSS_STATUS_SUCCESS) { d_fprintf(stderr, "Could not get dc name for %s\n", domain_name); - return False; + return false; } /* Display response */ d_printf("%s\n", response.data.dc_name); - return True; + return true; } /* Find a DC */ @@ -514,35 +514,35 @@ static bool wbinfo_dsgetdcname(const char *domain_name, uint32_t flags) if (winbindd_request_response(WINBINDD_DSGETDCNAME, &request, &response) != NSS_STATUS_SUCCESS) { d_fprintf(stderr, "Could not find dc for %s\n", domain_name); - return False; + return false; } /* Display response */ d_printf("%s\n", response.data.dc_name); - return True; + return true; } /* Check trust account password */ static bool wbinfo_check_secret(void) { - struct winbindd_response response; - NSS_STATUS result; + struct winbindd_response response; + NSS_STATUS result; - ZERO_STRUCT(response); + ZERO_STRUCT(response); - result = winbindd_request_response(WINBINDD_CHECK_MACHACC, NULL, &response); - - d_printf("checking the trust secret via RPC calls %s\n", + result = winbindd_request_response(WINBINDD_CHECK_MACHACC, NULL, &response); + + d_printf("checking the trust secret via RPC calls %s\n", (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); - if (result != NSS_STATUS_SUCCESS) - d_fprintf(stderr, "error code was %s (0x%x)\n", - response.data.auth.nt_status_string, + if (result != NSS_STATUS_SUCCESS) + d_fprintf(stderr, "error code was %s (0x%x)\n", + response.data.auth.nt_status_string, response.data.auth.nt_status); - + return result == NSS_STATUS_SUCCESS; } @@ -562,13 +562,13 @@ static bool wbinfo_uid_to_sid(uid_t uid) if (winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response) != NSS_STATUS_SUCCESS) - return False; + return false; /* Display response */ d_printf("%s\n", response.data.sid.sid); - return True; + return true; } /* Convert gid to sid */ @@ -587,13 +587,13 @@ static bool wbinfo_gid_to_sid(gid_t gid) if (winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response) != NSS_STATUS_SUCCESS) - return False; + return false; /* Display response */ d_printf("%s\n", response.data.sid.sid); - return True; + return true; } /* Convert sid to uid */ @@ -612,13 +612,13 @@ static bool wbinfo_sid_to_uid(char *sid) if (winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response) != NSS_STATUS_SUCCESS) - return False; + return false; /* Display response */ d_printf("%d\n", (int)response.data.uid); - return True; + return true; } static bool wbinfo_sid_to_gid(char *sid) @@ -635,13 +635,13 @@ static bool wbinfo_sid_to_gid(char *sid) if (winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response) != NSS_STATUS_SUCCESS) - return False; + return false; /* Display response */ d_printf("%d\n", (int)response.data.gid); - return True; + return true; } static bool wbinfo_allocate_uid(void) @@ -649,11 +649,11 @@ static bool wbinfo_allocate_uid(void) uid_t uid; if (!winbind_allocate_uid(&uid)) - return False; + return false; d_printf("New uid: %d\n", uid); - return True; + return true; } static bool wbinfo_allocate_gid(void) @@ -661,11 +661,11 @@ static bool wbinfo_allocate_gid(void) gid_t gid; if (!winbind_allocate_gid(&gid)) - return False; + return false; d_printf("New gid: %d\n", gid); - return True; + return true; } /* Convert sid to string */ @@ -684,15 +684,15 @@ static bool wbinfo_lookupsid(char *sid) if (winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response) != NSS_STATUS_SUCCESS) - return False; + return false; /* Display response */ - d_printf("%s%c%s %d\n", response.data.name.dom_name, - winbind_separator(), response.data.name.name, + d_printf("%s%c%s %d\n", response.data.name.dom_name, + winbind_separator(), response.data.name.name, response.data.name.type); - return True; + return true; } /* Lookup a list of RIDs */ @@ -725,18 +725,18 @@ static bool wbinfo_lookuprids(char *domain, char *arg) if (winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response) != NSS_STATUS_SUCCESS) { d_printf("Could not get domain sid for %s\n", request.domain_name); - return False; + return false; } if (!string_to_sid(&sid, response.data.domain_info.sid)) { d_printf("Could not convert %s to sid\n", response.data.domain_info.sid); - return False; + return false; } mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { d_printf("talloc_new failed\n"); - return False; + return false; } num_rids = 0; @@ -750,14 +750,14 @@ static bool wbinfo_lookuprids(char *domain, char *arg) if (rids == NULL) { TALLOC_FREE(mem_ctx); - return False; + return false; } if (!winbind_lookup_rids(mem_ctx, &sid, num_rids, rids, &domain_name, &names, &types)) { d_printf("winbind_lookup_rids failed\n"); TALLOC_FREE(mem_ctx); - return False; + return false; } d_printf("Domain: %s\n", domain_name); @@ -768,7 +768,7 @@ static bool wbinfo_lookuprids(char *domain, char *arg) } TALLOC_FREE(mem_ctx); - return True; + return true; } /* Convert string to sid */ @@ -783,18 +783,18 @@ static bool wbinfo_lookupname(char *name) ZERO_STRUCT(request); ZERO_STRUCT(response); - parse_wbinfo_domain_user(name, request.data.name.dom_name, + parse_wbinfo_domain_user(name, request.data.name.dom_name, request.data.name.name); if (winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response) != NSS_STATUS_SUCCESS) - return False; + return false; /* Display response */ d_printf("%s %s (%d)\n", response.data.sid.sid, sid_type_lookup(response.data.sid.type), response.data.sid.type); - return True; + return true; } /* Authenticate a user with a plaintext password */ @@ -843,8 +843,8 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags) if (result == NSS_STATUS_SUCCESS) { if (request.flags & WBFLAG_PAM_INFO3_TEXT) { - if (response.data.auth.info3.user_flgs & LOGON_CACHED_ACCOUNT) { - d_printf("user_flgs: LOGON_CACHED_ACCOUNT\n"); + if (response.data.auth.info3.user_flgs & NETLOGON_CACHED_ACCOUNT) { + d_printf("user_flgs: NETLOGON_CACHED_ACCOUNT\n"); } } @@ -863,139 +863,139 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags) static bool wbinfo_auth(char *username) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; - char *s = NULL; - char *p = NULL; - char *password = NULL; - char *name = NULL; + char *s = NULL; + char *p = NULL; + const char *password = NULL; + char *name = NULL; if ((s = SMB_STRDUP(username)) == NULL) { return false; } if ((p = strchr(s, '%')) != NULL) { - *p = 0; + *p = 0; p++; + password = p; + } else { + password = ""; } name = s; - password = p; wbc_status = wbcAuthenticateUser(name, password); - d_printf("plaintext password authentication %s\n", + d_printf("plaintext password authentication %s\n", WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed"); #if 0 if (response.data.auth.nt_status) d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n", - response.data.auth.nt_status_string, + response.data.auth.nt_status_string, response.data.auth.nt_status, response.data.auth.error_string); #endif SAFE_FREE(s); - return WBC_ERROR_IS_OK(wbc_status); + return WBC_ERROR_IS_OK(wbc_status); } /* Authenticate a user with a challenge/response */ static bool wbinfo_auth_crap(char *username) { - struct winbindd_request request; - struct winbindd_response response; - NSS_STATUS result; - fstring name_user; - fstring name_domain; - fstring pass; - char *p; - - /* Send off request */ - - ZERO_STRUCT(request); - ZERO_STRUCT(response); + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcAuthUserParams params; + struct wbcAuthUserInfo *info = NULL; + struct wbcAuthErrorInfo *err = NULL; + DATA_BLOB lm = data_blob_null; + DATA_BLOB nt = data_blob_null; + fstring name_user; + fstring name_domain; + fstring pass; + char *p; - p = strchr(username, '%'); + p = strchr(username, '%'); - if (p) { - *p = 0; - fstrcpy(pass, p + 1); + if (p) { + *p = 0; + fstrcpy(pass, p + 1); } parse_wbinfo_domain_user(username, name_domain, name_user); - request.data.auth_crap.logon_parameters = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT; + params.account_name = name_user; + params.domain_name = name_domain; + params.workstation_name = NULL; - fstrcpy(request.data.auth_crap.user, name_user); + params.flags = 0; + params.parameter_control= WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | + WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT; - fstrcpy(request.data.auth_crap.domain, - name_domain); + params.level = WBC_AUTH_USER_LEVEL_RESPONSE; + + generate_random_buffer(params.password.response.challenge, 8); - generate_random_buffer(request.data.auth_crap.chal, 8); - if (lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; - DATA_BLOB names_blob; + DATA_BLOB names_blob; - DATA_BLOB lm_response; - DATA_BLOB nt_response; + server_chal = data_blob(params.password.response.challenge, 8); - server_chal = data_blob(request.data.auth_crap.chal, 8); - /* Pretend this is a login to 'us', for blob purposes */ names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup()); - - if (!SMBNTLMv2encrypt(name_user, name_domain, pass, &server_chal, + + if (!SMBNTLMv2encrypt(name_user, name_domain, pass, &server_chal, &names_blob, - &lm_response, &nt_response, NULL)) { + &lm, &nt, NULL)) { data_blob_free(&names_blob); data_blob_free(&server_chal); - return False; + return false; } data_blob_free(&names_blob); data_blob_free(&server_chal); - memcpy(request.data.auth_crap.nt_resp, nt_response.data, - MIN(nt_response.length, - sizeof(request.data.auth_crap.nt_resp))); - request.data.auth_crap.nt_resp_len = nt_response.length; - - memcpy(request.data.auth_crap.lm_resp, lm_response.data, - MIN(lm_response.length, - sizeof(request.data.auth_crap.lm_resp))); - request.data.auth_crap.lm_resp_len = lm_response.length; - - data_blob_free(&nt_response); - data_blob_free(&lm_response); - } else { - if (lp_client_lanman_auth() - && SMBencrypt(pass, request.data.auth_crap.chal, - (uchar *)request.data.auth_crap.lm_resp)) { - request.data.auth_crap.lm_resp_len = 24; - } else { - request.data.auth_crap.lm_resp_len = 0; + if (lp_client_lanman_auth()) { + bool ok; + lm = data_blob(NULL, 24); + ok = SMBencrypt(pass, params.password.response.challenge, + lm.data); + if (!ok) { + data_blob_free(&lm); + } } - SMBNTencrypt(pass, request.data.auth_crap.chal, - (uchar *)request.data.auth_crap.nt_resp); - - request.data.auth_crap.nt_resp_len = 24; + nt = data_blob(NULL, 24); + SMBNTencrypt(pass, params.password.response.challenge, + nt.data); } - result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response); + params.password.response.nt_length = nt.length; + params.password.response.nt_data = nt.data; + params.password.response.lm_length = lm.length; + params.password.response.lm_data = lm.data; + + wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); /* Display response */ - d_printf("challenge/response password authentication %s\n", - (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); + d_printf("challenge/response password authentication %s\n", + WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed"); - if (response.data.auth.nt_status) + if (wbc_status == WBC_ERR_AUTH_ERROR) { d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n", - response.data.auth.nt_status_string, - response.data.auth.nt_status, - response.data.auth.error_string); + err->nt_string, + err->nt_status, + err->display_string); + wbcFreeMemory(err); + } else if (WBC_ERROR_IS_OK(wbc_status)) { + wbcFreeMemory(info); + } + + data_blob_free(&nt); + data_blob_free(&lm); - return result == NSS_STATUS_SUCCESS; + return WBC_ERROR_IS_OK(wbc_status); } /* Authenticate a user with a plaintext password and set a token */ @@ -1004,23 +1004,23 @@ static bool wbinfo_klog(char *username) { struct winbindd_request request; struct winbindd_response response; - NSS_STATUS result; - char *p; + NSS_STATUS result; + char *p; /* Send off request */ ZERO_STRUCT(request); ZERO_STRUCT(response); - p = strchr(username, '%'); + p = strchr(username, '%'); - if (p) { - *p = 0; - fstrcpy(request.data.auth.user, username); - fstrcpy(request.data.auth.pass, p + 1); - *p = '%'; - } else { - fstrcpy(request.data.auth.user, username); + if (p) { + *p = 0; + fstrcpy(request.data.auth.user, username); + fstrcpy(request.data.auth.pass, p + 1); + *p = '%'; + } else { + fstrcpy(request.data.auth.user, username); fstrcpy(request.data.auth.pass, getpass("Password: ")); } @@ -1030,30 +1030,30 @@ static bool wbinfo_klog(char *username) /* Display response */ - d_printf("plaintext password authentication %s\n", - (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); + d_printf("plaintext password authentication %s\n", + (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); if (response.data.auth.nt_status) d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n", - response.data.auth.nt_status_string, + response.data.auth.nt_status_string, response.data.auth.nt_status, response.data.auth.error_string); if (result != NSS_STATUS_SUCCESS) - return False; + return false; if (response.extra_data.data == NULL) { d_fprintf(stderr, "Did not get token data\n"); - return False; + return false; } if (!afs_settoken_str((char *)response.extra_data.data)) { d_fprintf(stderr, "Could not set token\n"); - return False; + return false; } d_printf("Successfully created AFS token\n"); - return True; + return true; } /* Print domain users */ @@ -1081,12 +1081,12 @@ static bool print_domain_users(const char *domain) if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) != NSS_STATUS_SUCCESS) - return False; + return false; /* Look through extra data */ if (!response.extra_data.data) - return False; + return false; extra_data = (const char *)response.extra_data.data; @@ -1097,7 +1097,7 @@ static bool print_domain_users(const char *domain) SAFE_FREE(response.extra_data.data); - return True; + return true; } /* Print domain groups */ @@ -1122,12 +1122,12 @@ static bool print_domain_groups(const char *domain) if (winbindd_request_response(WINBINDD_LIST_GROUPS, &request, &response) != NSS_STATUS_SUCCESS) - return False; + return false; /* Look through extra data */ if (!response.extra_data.data) - return False; + return false; extra_data = (const char *)response.extra_data.data; @@ -1138,7 +1138,7 @@ static bool print_domain_groups(const char *domain) SAFE_FREE(response.extra_data.data); - return True; + return true; } /* Set the authorised user for winbindd access in secrets.tdb */ @@ -1161,7 +1161,7 @@ static bool wbinfo_set_auth_user(char *username) } else { char *thepass = getpass("Password: "); if (thepass) { - password = thepass; + password = thepass; } else password = ""; } @@ -1175,7 +1175,7 @@ static bool wbinfo_set_auth_user(char *username) if (!secrets_store(SECRETS_AUTH_USER, user, strlen(user) + 1)) { d_fprintf(stderr, "error storing username\n"); - return False; + return false; } /* We always have a domain name added by the @@ -1184,7 +1184,7 @@ static bool wbinfo_set_auth_user(char *username) if (!secrets_store(SECRETS_AUTH_DOMAIN, domain, strlen(domain) + 1)) { d_fprintf(stderr, "error storing domain name\n"); - return False; + return false; } } else { @@ -1197,13 +1197,13 @@ static bool wbinfo_set_auth_user(char *username) if (!secrets_store(SECRETS_AUTH_PASSWORD, password, strlen(password) + 1)) { d_fprintf(stderr, "error storing password\n"); - return False; + return false; } } else secrets_delete(SECRETS_AUTH_PASSWORD); - return True; + return true; } static void wbinfo_get_auth_user(void) @@ -1211,7 +1211,7 @@ static void wbinfo_get_auth_user(void) char *user, *domain, *password; /* Lift data from secrets file */ - + secrets_fetch_ipc_userpass(&user, &domain, &password); if ((!user || !*user) && (!domain || !*domain ) && (!password || !*password)){ @@ -1241,10 +1241,10 @@ static bool wbinfo_ping(void) /* Display response */ - d_printf("Ping to winbindd %s on fd %d\n", - (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", winbindd_fd); + d_printf("Ping to winbindd %s on fd %d\n", + (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", winbindd_fd); - return result == NSS_STATUS_SUCCESS; + return result == NSS_STATUS_SUCCESS; } /* Main program */ @@ -1270,7 +1270,7 @@ enum { int main(int argc, char **argv, char **envp) { int opt; - TALLOC_CTX *frame = talloc_stackframe(); + TALLOC_CTX *frame = talloc_stackframe(); poptContext pc; static char *string_arg; static char *opt_domain_name; @@ -1280,7 +1280,7 @@ int main(int argc, char **argv, char **envp) struct poptOption long_options[] = { POPT_AUTOHELP - /* longName, shortName, argInfo, argPtr, value, descrip, + /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ { "domain-users", 'u', POPT_ARG_NONE, 0, 'u', "Lists all domain users", "domain"}, @@ -1354,7 +1354,7 @@ int main(int argc, char **argv, char **envp) poptFreeContext(pc); - if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, True)) { + if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, true)) { d_fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n", get_dyn_CONFIGFILE(), strerror(errno)); exit(1); @@ -1458,7 +1458,7 @@ int main(int argc, char **argv, char **envp) } break; case 'm': - if (!wbinfo_list_domains(False)) { + if (!wbinfo_list_domains(false)) { d_fprintf(stderr, "Could not list trusted domains\n"); goto done; } @@ -1518,18 +1518,18 @@ int main(int argc, char **argv, char **envp) } break; case 'a': { - bool got_error = False; + bool got_error = false; if (!wbinfo_auth(string_arg)) { d_fprintf(stderr, "Could not authenticate user %s with " "plaintext password\n", string_arg); - got_error = True; + got_error = true; } if (!wbinfo_auth_crap(string_arg)) { d_fprintf(stderr, "Could not authenticate user %s with " "challenge/response\n", string_arg); - got_error = True; + got_error = true; } if (got_error) @@ -1580,7 +1580,7 @@ int main(int argc, char **argv, char **envp) } break; case OPT_SEPARATOR: { - const char sep = winbind_separator_int(True); + const char sep = winbind_separator_int(true); if ( !sep ) { goto done; } @@ -1588,7 +1588,7 @@ int main(int argc, char **argv, char **envp) break; } case OPT_LIST_ALL_DOMAINS: - if (!wbinfo_list_domains(True)) { + if (!wbinfo_list_domains(true)) { goto done; } break; diff --git a/source3/nsswitch/winbind_client.h b/source3/nsswitch/winbind_client.h index 2a3956e1fd..757f5869e9 100644 --- a/source3/nsswitch/winbind_client.h +++ b/source3/nsswitch/winbind_client.h @@ -14,9 +14,14 @@ NSS_STATUS winbindd_priv_request_response(int req_type, struct winbindd_response *response); int winbindd_read_reply(struct winbindd_response *response); -bool winbind_env_set(void); -bool winbind_off(void); -bool winbind_on(void); +#define winbind_env_set() \ + (strcmp(getenv(WINBINDD_DONT_ENV)?getenv(WINBINDD_DONT_ENV):"0","1") == 0) + +#define winbind_off() \ + (setenv(WINBINDD_DONT_ENV, "1", 1) == 0) + +#define winbind_on() \ + (setenv(WINBINDD_DONT_ENV, "0", 1) == 0) int winbind_write_sock(void *buffer, int count, int recursing, int need_priv); int winbind_read_sock(void *buffer, int count); diff --git a/source3/nsswitch/winbind_krb5_locator.c b/source3/nsswitch/winbind_krb5_locator.c index eef57ca2c0..33a68f0cdc 100644 --- a/source3/nsswitch/winbind_krb5_locator.c +++ b/source3/nsswitch/winbind_krb5_locator.c @@ -90,7 +90,7 @@ static const char *family_name(int family) return "AF_UNSPEC"; case AF_INET: return "AF_INET"; -#if defined(HAVE_IPv6) +#if defined(HAVE_IPV6) case AF_INET6: return "AF_INET6"; #endif @@ -137,9 +137,9 @@ static int smb_krb5_locator_lookup_sanity_check(enum locate_service_type svc, case AF_UNSPEC: case AF_INET: break; -#if defined(HAVE_IPv6) - case AF_INET6: /* not yet */ - return KRB5_PLUGIN_NO_HANDLE; +#if defined(HAVE_IPV6) + case AF_INET6: + break; #endif default: return EINVAL; diff --git a/source3/nsswitch/winbind_struct_protocol.h b/source3/nsswitch/winbind_struct_protocol.h index 12ca1e55c8..e81813c77b 100644 --- a/source3/nsswitch/winbind_struct_protocol.h +++ b/source3/nsswitch/winbind_struct_protocol.h @@ -431,6 +431,7 @@ struct winbindd_response { fstring logon_srv; fstring logon_dom; } info3; + fstring unix_username; } auth; struct { fstring name; diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c index c822fc78b9..35649dfda2 100644 --- a/source3/nsswitch/wins.c +++ b/source3/nsswitch/wins.c @@ -147,7 +147,7 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count) static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count) { int fd; - struct in_addr ip; + struct sockaddr_storage ss; struct nmb_name nname; NODE_STATUS_STRUCT *status; @@ -160,8 +160,10 @@ static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count) return NULL; make_nmb_name(&nname, "*", 0); - (void)interpret_addr2(&ip,addr); - status = node_status_query(fd,&nname,ip, count, NULL); + if (!interpret_string_addr(&ss, addr, AI_NUMERICHOST)) { + return NULL; + } + status = node_status_query(fd, &nname, &ss, count, NULL); close(fd); return status; |