diff options
author | Andrew Tridgell <tridge@samba.org> | 2008-12-03 17:47:39 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2008-12-03 17:47:39 +1100 |
commit | a226d86dcec393b2cd657d5441c3041dfdf5cd8f (patch) | |
tree | 03ef7f3207607a4e5351bf50892b0a39dcf6f219 /source3/nsswitch | |
parent | 30eff4f31b497ac94d8ee02ee2ec24bc8865ce0d (diff) | |
parent | 85b8cccab072bab263061654b677bc84826646c9 (diff) | |
download | samba-a226d86dcec393b2cd657d5441c3041dfdf5cd8f.tar.gz samba-a226d86dcec393b2cd657d5441c3041dfdf5cd8f.tar.bz2 samba-a226d86dcec393b2cd657d5441c3041dfdf5cd8f.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/libwbclient/wbc_idmap.c | 154 | ||||
-rw-r--r-- | source3/nsswitch/libwbclient/wbc_pam.c | 15 | ||||
-rw-r--r-- | source3/nsswitch/libwbclient/wbc_pwd.c | 216 | ||||
-rw-r--r-- | source3/nsswitch/libwbclient/wbclient.c | 2 | ||||
-rw-r--r-- | source3/nsswitch/libwbclient/wbclient.h | 55 | ||||
-rw-r--r-- | source3/nsswitch/pam_winbind.c | 187 | ||||
-rw-r--r-- | source3/nsswitch/pam_winbind.h | 15 | ||||
-rw-r--r-- | source3/nsswitch/wb_common.c | 2 | ||||
-rw-r--r-- | source3/nsswitch/wbinfo.c | 181 | ||||
-rw-r--r-- | source3/nsswitch/winbind_struct_protocol.h | 12 | ||||
-rw-r--r-- | source3/nsswitch/wins.c | 63 |
11 files changed, 785 insertions, 117 deletions
diff --git a/source3/nsswitch/libwbclient/wbc_idmap.c b/source3/nsswitch/libwbclient/wbc_idmap.c index 1615fd33ee..81b369c87c 100644 --- a/source3/nsswitch/libwbclient/wbc_idmap.c +++ b/source3/nsswitch/libwbclient/wbc_idmap.c @@ -24,7 +24,7 @@ #include "libwbclient.h" -/** @brief Convert a Windows SID to a Unix uid +/** @brief Convert a Windows SID to a Unix uid, allocating an uid if needed * * @param *sid Pointer to the domain SID to be resolved * @param *puid Pointer to the resolved uid_t value @@ -71,7 +71,22 @@ wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid) return wbc_status; } -/** @brief Convert a Unix uid to a Windows SID +/** @brief Convert a Windows SID to a Unix uid if there already is a mapping + * + * @param *sid Pointer to the domain SID to be resolved + * @param *puid Pointer to the resolved uid_t value + * + * @return #wbcErr + * + **/ + +wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid, + uid_t *puid) +{ + return WBC_ERR_NOT_IMPLEMENTED; +} + +/** @brief Convert a Unix uid to a Windows SID, allocating a SID if needed * * @param uid Unix uid to be resolved * @param *sid Pointer to the resolved domain SID @@ -112,7 +127,22 @@ done: return wbc_status; } -/** @brief Convert a Windows SID to a Unix gid +/** @brief Convert a Unix uid to a Windows SID if there already is a mapping + * + * @param uid Unix uid to be resolved + * @param *sid Pointer to the resolved domain SID + * + * @return #wbcErr + * + **/ + +wbcErr wbcQueryUidToSid(uid_t uid, + struct wbcDomainSid *sid) +{ + return WBC_ERR_NOT_IMPLEMENTED; +} + +/** @brief Convert a Windows SID to a Unix gid, allocating a gid if needed * * @param *sid Pointer to the domain SID to be resolved * @param *pgid Pointer to the resolved gid_t value @@ -159,7 +189,22 @@ wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid) return wbc_status; } -/** @brief Convert a Unix uid to a Windows SID +/** @brief Convert a Windows SID to a Unix gid if there already is a mapping + * + * @param *sid Pointer to the domain SID to be resolved + * @param *pgid Pointer to the resolved gid_t value + * + * @return #wbcErr + * + **/ + +wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid, + gid_t *pgid) +{ + return WBC_ERR_NOT_IMPLEMENTED; +} + +/** @brief Convert a Unix gid to a Windows SID, allocating a SID if needed * * @param gid Unix gid to be resolved * @param *sid Pointer to the resolved domain SID @@ -200,6 +245,21 @@ done: return wbc_status; } +/** @brief Convert a Unix gid to a Windows SID if there already is a mapping + * + * @param gid Unix gid to be resolved + * @param *sid Pointer to the resolved domain SID + * + * @return #wbcErr + * + **/ + +wbcErr wbcQueryGidToSid(gid_t gid, + struct wbcDomainSid *sid) +{ + return WBC_ERR_NOT_IMPLEMENTED; +} + /** @brief Obtain a new uid from Winbind * * @param *puid *pointer to the allocated uid @@ -362,6 +422,92 @@ wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid) return wbc_status; } +/** @brief Remove a user id mapping + * + * @param uid Uid of the mapping to remove. + * @param *sid Pointer to the sid of the mapping to remove. + * + * @return #wbcErr + **/ +wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid) +{ + struct winbindd_request request; + struct winbindd_response response; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + char *sid_string = NULL; + + if (!sid) { + return WBC_ERR_INVALID_PARAM; + } + + /* Initialise request */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + /* Make request */ + + request.data.dual_idmapset.id = uid; + request.data.dual_idmapset.type = _ID_TYPE_UID; + + wbc_status = wbcSidToString(sid, &sid_string); + BAIL_ON_WBC_ERROR(wbc_status); + + strncpy(request.data.dual_idmapset.sid, sid_string, + sizeof(request.data.dual_idmapset.sid)-1); + wbcFreeMemory(sid_string); + + wbc_status = wbcRequestResponse(WINBINDD_REMOVE_MAPPING, + &request, &response); + BAIL_ON_WBC_ERROR(wbc_status); + + done: + return wbc_status; +} + +/** @brief Remove a group id mapping + * + * @param gid Gid of the mapping to remove. + * @param *sid Pointer to the sid of the mapping to remove. + * + * @return #wbcErr + **/ +wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid) +{ + struct winbindd_request request; + struct winbindd_response response; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + char *sid_string = NULL; + + if (!sid) { + return WBC_ERR_INVALID_PARAM; + } + + /* Initialise request */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + /* Make request */ + + request.data.dual_idmapset.id = gid; + request.data.dual_idmapset.type = _ID_TYPE_GID; + + wbc_status = wbcSidToString(sid, &sid_string); + BAIL_ON_WBC_ERROR(wbc_status); + + strncpy(request.data.dual_idmapset.sid, sid_string, + sizeof(request.data.dual_idmapset.sid)-1); + wbcFreeMemory(sid_string); + + wbc_status = wbcRequestResponse(WINBINDD_REMOVE_MAPPING, + &request, &response); + BAIL_ON_WBC_ERROR(wbc_status); + + done: + return wbc_status; +} + /** @brief Set the highwater mark for allocated uids. * * @param uid_hwm The new uid highwater mark value diff --git a/source3/nsswitch/libwbclient/wbc_pam.c b/source3/nsswitch/libwbclient/wbc_pam.c index 713ba2e65b..401d2ad2c3 100644 --- a/source3/nsswitch/libwbclient/wbc_pam.c +++ b/source3/nsswitch/libwbclient/wbc_pam.c @@ -1095,3 +1095,18 @@ done: return wbc_status; } + +/** @brief Authenticate a user with cached credentials + * + * @param *params Pointer to a wbcCredentialCacheParams structure + * @param **info Pointer to a pointer to a wbcCredentialCacheInfo structure + * @param **error Pointer to a pointer to a wbcAuthErrorInfo structure + * + * @return #wbcErr + **/ +wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params, + struct wbcCredentialCacheInfo **info, + struct wbcAuthErrorInfo **error) +{ + return WBC_ERR_NOT_IMPLEMENTED; +} diff --git a/source3/nsswitch/libwbclient/wbc_pwd.c b/source3/nsswitch/libwbclient/wbc_pwd.c index 0d17b312ef..d54a5af4fc 100644 --- a/source3/nsswitch/libwbclient/wbc_pwd.c +++ b/source3/nsswitch/libwbclient/wbc_pwd.c @@ -24,6 +24,16 @@ #include "libwbclient.h" +/** @brief The maximum number of pwent structs to get from winbindd + * + */ +#define MAX_GETPWENT_USERS 500 + +/** @brief The maximum number of grent structs to get from winbindd + * + */ +#define MAX_GETGRENT_GROUPS 500 + /** * **/ @@ -284,6 +294,21 @@ wbcErr wbcGetgrgid(gid_t gid, struct group **grp) return wbc_status; } +/** @brief Number of cached passwd structs + * + */ +static uint32_t pw_cache_size; + +/** @brief Position of the pwent context + * + */ +static uint32_t pw_cache_idx; + +/** @brief Winbindd response containing the passwd structs + * + */ +static struct winbindd_response pw_response; + /** @brief Reset the passwd iterator * * @return #wbcErr @@ -293,6 +318,15 @@ wbcErr wbcSetpwent(void) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + if (pw_cache_size > 0) { + pw_cache_idx = pw_cache_size = 0; + if (pw_response.extra_data.data) { + free(pw_response.extra_data.data); + } + } + + ZERO_STRUCT(pw_response); + wbc_status = wbcRequestResponse(WINBINDD_SETPWENT, NULL, NULL); BAIL_ON_WBC_ERROR(wbc_status); @@ -310,6 +344,13 @@ wbcErr wbcEndpwent(void) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + if (pw_cache_size > 0) { + pw_cache_idx = pw_cache_size = 0; + if (pw_response.extra_data.data) { + free(pw_response.extra_data.data); + } + } + wbc_status = wbcRequestResponse(WINBINDD_ENDPWENT, NULL, NULL); BAIL_ON_WBC_ERROR(wbc_status); @@ -320,16 +361,70 @@ wbcErr wbcEndpwent(void) /** @brief Return the next struct passwd* entry from the pwent iterator * - * @param **pwd Pointer to resulting struct group* from the query. + * @param **pwd Pointer to resulting struct passwd* from the query. * * @return #wbcErr **/ wbcErr wbcGetpwent(struct passwd **pwd) { - return WBC_ERR_NOT_IMPLEMENTED; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct winbindd_request request; + struct winbindd_pw *wb_pw; + + /* If there's a cached result, return that. */ + if (pw_cache_idx < pw_cache_size) { + goto return_result; + } + + /* Otherwise, query winbindd for some entries. */ + + pw_cache_idx = 0; + + if (pw_response.extra_data.data) { + free(pw_response.extra_data.data); + ZERO_STRUCT(pw_response); + } + + ZERO_STRUCT(request); + request.data.num_entries = MAX_GETPWENT_USERS; + + wbc_status = wbcRequestResponse(WINBINDD_GETPWENT, &request, + &pw_response); + + BAIL_ON_WBC_ERROR(wbc_status); + + pw_cache_size = pw_response.data.num_entries; + +return_result: + + wb_pw = (struct winbindd_pw *) pw_response.extra_data.data; + + *pwd = copy_passwd_entry(&wb_pw[pw_cache_idx]); + + BAIL_ON_PTR_ERROR(*pwd, wbc_status); + + pw_cache_idx++; + +done: + return wbc_status; } +/** @brief Number of cached group structs + * + */ +static uint32_t gr_cache_size; + +/** @brief Position of the grent context + * + */ +static uint32_t gr_cache_idx; + +/** @brief Winbindd response containing the group structs + * + */ +static struct winbindd_response gr_response; + /** @brief Reset the group iterator * * @return #wbcErr @@ -339,6 +434,15 @@ wbcErr wbcSetgrent(void) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + if (gr_cache_size > 0) { + gr_cache_idx = gr_cache_size = 0; + if (gr_response.extra_data.data) { + free(gr_response.extra_data.data); + } + } + + ZERO_STRUCT(gr_response); + wbc_status = wbcRequestResponse(WINBINDD_SETGRENT, NULL, NULL); BAIL_ON_WBC_ERROR(wbc_status); @@ -356,6 +460,13 @@ wbcErr wbcEndgrent(void) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + if (gr_cache_size > 0) { + gr_cache_idx = gr_cache_size = 0; + if (gr_response.extra_data.data) { + free(gr_response.extra_data.data); + } + } + wbc_status = wbcRequestResponse(WINBINDD_ENDGRENT, NULL, NULL); BAIL_ON_WBC_ERROR(wbc_status); @@ -364,7 +475,7 @@ wbcErr wbcEndgrent(void) return wbc_status; } -/** @brief Return the next struct passwd* entry from the pwent iterator +/** @brief Return the next struct group* entry from the pwent iterator * * @param **grp Pointer to resulting struct group* from the query. * @@ -373,7 +484,104 @@ wbcErr wbcEndgrent(void) wbcErr wbcGetgrent(struct group **grp) { - return WBC_ERR_NOT_IMPLEMENTED; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct winbindd_request request; + struct winbindd_gr *wb_gr; + uint32_t mem_ofs; + + /* If there's a cached result, return that. */ + if (gr_cache_idx < gr_cache_size) { + goto return_result; + } + + /* Otherwise, query winbindd for some entries. */ + + gr_cache_idx = 0; + + if (gr_response.extra_data.data) { + free(gr_response.extra_data.data); + ZERO_STRUCT(gr_response); + } + + ZERO_STRUCT(request); + request.data.num_entries = MAX_GETGRENT_GROUPS; + + wbc_status = wbcRequestResponse(WINBINDD_GETGRENT, &request, + &gr_response); + + BAIL_ON_WBC_ERROR(wbc_status); + + gr_cache_size = gr_response.data.num_entries; + +return_result: + + wb_gr = (struct winbindd_gr *) gr_response.extra_data.data; + + mem_ofs = wb_gr[gr_cache_idx].gr_mem_ofs + + gr_cache_size * sizeof(struct winbindd_gr); + + *grp = copy_group_entry(&wb_gr[gr_cache_idx], + ((char *)gr_response.extra_data.data)+mem_ofs); + + BAIL_ON_PTR_ERROR(*grp, wbc_status); + + gr_cache_idx++; + +done: + return wbc_status; +} + +/** @brief Return the next struct group* entry from the pwent iterator + * + * This is similar to #wbcGetgrent, just that the member list is empty + * + * @param **grp Pointer to resulting struct group* from the query. + * + * @return #wbcErr + **/ + +wbcErr wbcGetgrlist(struct group **grp) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct winbindd_request request; + struct winbindd_gr *wb_gr; + + /* If there's a cached result, return that. */ + if (gr_cache_idx < gr_cache_size) { + goto return_result; + } + + /* Otherwise, query winbindd for some entries. */ + + gr_cache_idx = 0; + + if (gr_response.extra_data.data) { + free(gr_response.extra_data.data); + ZERO_STRUCT(gr_response); + } + + ZERO_STRUCT(request); + request.data.num_entries = MAX_GETGRENT_GROUPS; + + wbc_status = wbcRequestResponse(WINBINDD_GETGRLST, &request, + &gr_response); + + BAIL_ON_WBC_ERROR(wbc_status); + + gr_cache_size = gr_response.data.num_entries; + +return_result: + + wb_gr = (struct winbindd_gr *) gr_response.extra_data.data; + + *grp = copy_group_entry(&wb_gr[gr_cache_idx], NULL); + + BAIL_ON_PTR_ERROR(*grp, wbc_status); + + gr_cache_idx++; + +done: + return wbc_status; } /** @brief Return the unix group array belonging to the given user diff --git a/source3/nsswitch/libwbclient/wbclient.c b/source3/nsswitch/libwbclient/wbclient.c index bdde562a93..c0b7e0675a 100644 --- a/source3/nsswitch/libwbclient/wbclient.c +++ b/source3/nsswitch/libwbclient/wbclient.c @@ -59,7 +59,7 @@ wbcErr wbcRequestResponse(int cmd, wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; NSS_STATUS nss_status; - /* for some calls the request and/or response cna be NULL */ + /* for some calls the request and/or response can be NULL */ nss_status = winbindd_request_response(cmd, request, response); diff --git a/source3/nsswitch/libwbclient/wbclient.h b/source3/nsswitch/libwbclient/wbclient.h index 662e0cdf8d..cb31360407 100644 --- a/source3/nsswitch/libwbclient/wbclient.h +++ b/source3/nsswitch/libwbclient/wbclient.h @@ -57,9 +57,12 @@ const char *wbcErrorString(wbcErr error); /** * @brief Some useful details about the wbclient library * + * 0.1: Initial version + * 0.2: Added wbcRemoveUidMapping() + * Added wbcRemoveGidMapping() **/ #define WBCLIENT_MAJOR_VERSION 0 -#define WBCLIENT_MINOR_VERSION 1 +#define WBCLIENT_MINOR_VERSION 2 #define WBCLIENT_VENDOR_VERSION "Samba libwbclient" struct wbcLibraryDetails { uint16_t major_version; @@ -358,7 +361,7 @@ struct wbcLogonUserInfo { #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_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 @@ -385,7 +388,7 @@ struct wbcLogonUserInfo { #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_PW_EXPIRED 0x00020000 /* 1 Password Expired */ #define WBC_ACB_NO_AUTH_DATA_REQD 0x00080000 /* 1 = No authorization data required */ struct wbcAuthErrorInfo { @@ -437,6 +440,30 @@ struct wbcLogoffUserParams { struct wbcNamedBlob *blobs; }; +/** @brief Credential cache log-on parameters + * + */ + +struct wbcCredentialCacheParams { + const char *account_name; + const char *domain_name; + enum wbcCredentialCacheLevel { + WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP = 1 + } level; + size_t num_blobs; + struct wbcNamedBlob *blobs; +}; + + +/** @brief Info returned by credential cache auth + * + */ + +struct wbcCredentialCacheInfo { + size_t num_blobs; + struct wbcNamedBlob *blobs; +}; + /* * DomainControllerInfo struct */ @@ -538,15 +565,27 @@ wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid, wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid); +wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid, + uid_t *puid); + wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid); +wbcErr wbcQueryUidToSid(uid_t uid, + struct wbcDomainSid *sid); + wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid); +wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid, + gid_t *pgid); + wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid); +wbcErr wbcQueryGidToSid(gid_t gid, + struct wbcDomainSid *sid); + wbcErr wbcAllocateUid(uid_t *puid); wbcErr wbcAllocateGid(gid_t *pgid); @@ -555,6 +594,10 @@ wbcErr wbcSetUidMapping(uid_t uid, const struct wbcDomainSid *sid); wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid); +wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid); + +wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid); + wbcErr wbcSetUidHwm(uid_t uid_hwm); wbcErr wbcSetGidHwm(gid_t gid_hwm); @@ -583,6 +626,8 @@ wbcErr wbcEndgrent(void); wbcErr wbcGetgrent(struct group **grp); +wbcErr wbcGetgrlist(struct group **grp); + wbcErr wbcGetGroups(const char *account, uint32_t *num_groups, gid_t **_groups); @@ -662,6 +707,10 @@ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params, enum wbcPasswordChangeRejectReason *reject_reason, struct wbcUserPasswordPolicyInfo **policy); +wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params, + struct wbcCredentialCacheInfo **info, + struct wbcAuthErrorInfo **error); + /* * Resolve functions */ diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c index 1c927259e5..be22ff3f5e 100644 --- a/source3/nsswitch/pam_winbind.c +++ b/source3/nsswitch/pam_winbind.c @@ -147,6 +147,21 @@ static const char *_pam_error_code_str(int err) #define MAX_PASSWD_TRIES 3 +#ifdef HAVE_GETTEXT +static char initialized = 0; + +static inline void textdomain_init(void); +static inline void textdomain_init(void) +{ + if (!initialized) { + bindtextdomain(MODULE_NAME, dyn_LOCALEDIR); + initialized = 1; + } + return; +} +#endif + + /* * Work around the pam API that has functions with void ** as parameters * These lead to strict aliasing warnings with gcc. @@ -515,6 +530,10 @@ static int _pam_winbind_init_context(pam_handle_t *pamh, { struct pwb_context *r = NULL; +#ifdef HAVE_GETTEXT + textdomain_init(); +#endif + r = TALLOC_ZERO_P(NULL, struct pwb_context); if (!r) { return PAM_BUF_ERR; @@ -557,44 +576,44 @@ static const struct ntstatus_errors { const char *error_string; } ntstatus_errors[] = { {"NT_STATUS_OK", - "Success"}, + N_("Success")}, {"NT_STATUS_BACKUP_CONTROLLER", - "No primary Domain Controler available"}, + N_("No primary Domain Controler available")}, {"NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND", - "No domain controllers found"}, + N_("No domain controllers found")}, {"NT_STATUS_NO_LOGON_SERVERS", - "No logon servers"}, + N_("No logon servers")}, {"NT_STATUS_PWD_TOO_SHORT", - "Password too short"}, + N_("Password too short")}, {"NT_STATUS_PWD_TOO_RECENT", - "The password of this user is too recent to change"}, + N_("The password of this user is too recent to change")}, {"NT_STATUS_PWD_HISTORY_CONFLICT", - "Password is already in password history"}, + N_("Password is already in password history")}, {"NT_STATUS_PASSWORD_EXPIRED", - "Your password has expired"}, + N_("Your password has expired")}, {"NT_STATUS_PASSWORD_MUST_CHANGE", - "You need to change your password now"}, + N_("You need to change your password now")}, {"NT_STATUS_INVALID_WORKSTATION", - "You are not allowed to logon from this workstation"}, + N_("You are not allowed to logon from this workstation")}, {"NT_STATUS_INVALID_LOGON_HOURS", - "You are not allowed to logon at this time"}, + N_("You are not allowed to logon at this time")}, {"NT_STATUS_ACCOUNT_EXPIRED", - "Your account has expired. " - "Please contact your System administrator"}, /* SCNR */ + N_("Your account has expired. " + "Please contact your System administrator")}, /* SCNR */ {"NT_STATUS_ACCOUNT_DISABLED", - "Your account is disabled. " - "Please contact your System administrator"}, /* SCNR */ + N_("Your account is disabled. " + "Please contact your System administrator")}, /* SCNR */ {"NT_STATUS_ACCOUNT_LOCKED_OUT", - "Your account has been locked. " - "Please contact your System administrator"}, /* SCNR */ + N_("Your account has been locked. " + "Please contact your System administrator")}, /* SCNR */ {"NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT", - "Invalid Trust Account"}, + N_("Invalid Trust Account")}, {"NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT", - "Invalid Trust Account"}, + N_("Invalid Trust Account")}, {"NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT", - "Invalid Trust Account"}, + N_("Invalid Trust Account")}, {"NT_STATUS_ACCESS_DENIED", - "Access is denied"}, + N_("Access is denied")}, {NULL, NULL} }; @@ -604,7 +623,7 @@ static const char *_get_ntstatus_error_string(const char *nt_status_string) for (i=0; ntstatus_errors[i].ntstatus_string != NULL; i++) { if (!strcasecmp(ntstatus_errors[i].ntstatus_string, nt_status_string)) { - return ntstatus_errors[i].error_string; + return _(ntstatus_errors[i].error_string); } } return NULL; @@ -832,14 +851,14 @@ static bool _pam_send_password_expiry_message(struct pwb_context *ctx, if (days == 0) { _make_remark(ctx, PAM_TEXT_INFO, - "Your password expires today"); + _("Your password expires today")); return true; } if (days > 0 && days < warn_pwd_expire) { _make_remark_format(ctx, PAM_TEXT_INFO, - "Your password will expire in %d %s", - days, (days > 1) ? "days":"day"); + _("Your password will expire in %d %s"), + days, (days > 1) ? _("days"):_("day")); return true; } @@ -1231,9 +1250,9 @@ static void _pam_warn_logon_type(struct pwb_context *ctx, if (PAM_WB_GRACE_LOGON(info3_user_flgs)) { _make_remark(ctx, PAM_ERROR_MSG, - "Grace login. " - "Please change your password as soon you're " - "online again"); + _("Grace login. " + "Please change your password as soon you're " + "online again")); _pam_log_debug(ctx, LOG_DEBUG, "User %s logged on using grace logon\n", username); @@ -1241,9 +1260,9 @@ static void _pam_warn_logon_type(struct pwb_context *ctx, } else if (PAM_WB_CACHED_LOGON(info3_user_flgs)) { _make_remark(ctx, PAM_ERROR_MSG, - "Domain Controller unreachable, " - "using cached credentials instead. " - "Network resources may be unavailable"); + _("Domain Controller unreachable, " + "using cached credentials instead. " + "Network resources may be unavailable")); _pam_log_debug(ctx, LOG_DEBUG, "User %s logged on using cached credentials\n", username); @@ -1266,10 +1285,10 @@ static void _pam_warn_krb5_failure(struct pwb_context *ctx, { if (PAM_WB_KRB5_CLOCK_SKEW(info3_user_flgs)) { _make_remark(ctx, PAM_ERROR_MSG, - "Failed to establish your Kerberos Ticket cache " - "due time differences\n" - "with the domain controller. " - "Please verify the system time.\n"); + _("Failed to establish your Kerberos Ticket cache " + "due time differences\n" + "with the domain controller. " + "Please verify the system time.\n")); _pam_log_debug(ctx, LOG_DEBUG, "User %s: Clock skew when getting Krb5 TGT\n", username); @@ -1334,14 +1353,14 @@ static char *_pam_compose_pwd_restriction_string(struct pwb_context *ctx, goto failed; } - str = talloc_asprintf(ctx, "Your password "); + str = talloc_asprintf(ctx, _("Your password ")); if (!str) { goto failed; } if (i->min_length_password > 0) { str = talloc_asprintf_append(str, - "must be at least %d characters; ", + _("must be at least %d characters; "), i->min_length_password); if (!str) { goto failed; @@ -1350,8 +1369,8 @@ static char *_pam_compose_pwd_restriction_string(struct pwb_context *ctx, if (i->password_history > 0) { str = talloc_asprintf_append(str, - "cannot repeat any of your previous %d " - "passwords; ", + _("cannot repeat any of your previous %d " + "passwords; "), i->password_history); if (!str) { goto failed; @@ -1360,19 +1379,19 @@ static char *_pam_compose_pwd_restriction_string(struct pwb_context *ctx, if (i->password_properties & WBC_DOMAIN_PASSWORD_COMPLEX) { str = talloc_asprintf_append(str, - "must contain capitals, numerals " - "or punctuation; " - "and cannot contain your account " - "or full name; "); + _("must contain capitals, numerals " + "or punctuation; " + "and cannot contain your account " + "or full name; ")); if (!str) { goto failed; } } str = talloc_asprintf_append(str, - "Please type a different password. " - "Type a password which meets these requirements in " - "both text boxes."); + _("Please type a different password. " + "Type a password which meets these requirements in " + "both text boxes.")); if (!str) { goto failed; } @@ -1397,7 +1416,7 @@ static int _pam_create_homedir(struct pwb_context *ctx, if (mkdir(dirname, mode) != 0) { _make_remark_format(ctx, PAM_TEXT_INFO, - "Creating directory: %s failed: %s", + _("Creating directory: %s failed: %s"), dirname, strerror(errno)); _pam_log(ctx, LOG_ERR, "could not create dir: %s (%s)", dirname, strerror(errno)); @@ -1615,14 +1634,16 @@ static int winbind_auth_request(struct pwb_context *ctx, logon.username = user; logon.password = pass; - wbc_status = wbcAddNamedBlob(&logon.num_blobs, - &logon.blobs, - "krb5_cc_type", - 0, - (uint8_t *)cctype, - strlen(cctype)+1); - if (!WBC_ERROR_IS_OK(wbc_status)) { - goto done; + if (cctype) { + wbc_status = wbcAddNamedBlob(&logon.num_blobs, + &logon.blobs, + "krb5_cc_type", + 0, + (uint8_t *)cctype, + strlen(cctype)+1); + if (!WBC_ERROR_IS_OK(wbc_status)) { + goto done; + } } wbc_status = wbcAddNamedBlob(&logon.num_blobs, @@ -1645,14 +1666,16 @@ static int winbind_auth_request(struct pwb_context *ctx, goto done; } - wbc_status = wbcAddNamedBlob(&logon.num_blobs, - &logon.blobs, - "membership_of", - 0, - (uint8_t *)membership_of, - sizeof(membership_of)); - if (!WBC_ERROR_IS_OK(wbc_status)) { - goto done; + if (member) { + wbc_status = wbcAddNamedBlob(&logon.num_blobs, + &logon.blobs, + "membership_of", + 0, + (uint8_t *)membership_of, + sizeof(membership_of)); + if (!WBC_ERROR_IS_OK(wbc_status)) { + goto done; + } } wbc_status = wbcLogonUser(&logon, &info, &error, &policy); @@ -1851,8 +1874,8 @@ static int winbind_chauthtok_request(struct pwb_context *ctx, break; case WBC_PWD_CHANGE_REJECT_COMPLEXITY: _make_remark(ctx, PAM_ERROR_MSG, - "Password does not meet " - "complexity requirements"); + _("Password does not meet " + "complexity requirements")); break; default: _pam_log_debug(ctx, LOG_DEBUG, @@ -2293,7 +2316,7 @@ static int _pam_delete_cred(pam_handle_t *pamh, int flags, struct wbcLogoffUserParams logoff; struct wbcAuthErrorInfo *error = NULL; const char *user; - wbcErr wbc_status; + wbcErr wbc_status = WBC_ERR_SUCCESS; retval = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx); if (retval) { @@ -2310,7 +2333,7 @@ static int _pam_delete_cred(pam_handle_t *pamh, int flags, const char *ccname = NULL; struct passwd *pwd = NULL; - retval = pam_get_user(pamh, &user, "Username: "); + retval = pam_get_user(pamh, &user, _("Username: ")); if (retval) { _pam_log(ctx, LOG_ERR, "could not identify user"); @@ -2346,14 +2369,16 @@ static int _pam_delete_cred(pam_handle_t *pamh, int flags, logoff.username = user; - wbc_status = wbcAddNamedBlob(&logoff.num_blobs, - &logoff.blobs, - "ccfilename", - 0, - (uint8_t *)ccname, - strlen(ccname)+1); - if (!WBC_ERROR_IS_OK(wbc_status)) { - goto out; + if (ccname) { + wbc_status = wbcAddNamedBlob(&logoff.num_blobs, + &logoff.blobs, + "ccfilename", + 0, + (uint8_t *)ccname, + strlen(ccname)+1); + if (!WBC_ERROR_IS_OK(wbc_status)) { + goto out; + } } wbc_status = wbcAddNamedBlob(&logoff.num_blobs, @@ -2485,7 +2510,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, } retval = _winbind_read_password(ctx, ctx->ctrl, NULL, - "Password: ", NULL, + _("Password: "), NULL, &password); if (retval != PAM_SUCCESS) { @@ -2855,7 +2880,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, /* * First get the name of a user */ - ret = pam_get_user(pamh, &user, "Username: "); + ret = pam_get_user(pamh, &user, _("Username: ")); if (ret) { _pam_log(ctx, LOG_ERR, "password - could not identify user"); @@ -2893,7 +2918,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, /* instruct user what is happening */ -#define greeting "Changing password for" +#define greeting _("Changing password for") Announce = talloc_asprintf(ctx, "%s %s", greeting, user); if (!Announce) { _pam_log(ctx, LOG_CRIT, @@ -2906,7 +2931,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, lctrl = ctx->ctrl | WINBIND__OLD_PASSWORD; ret = _winbind_read_password(ctx, lctrl, Announce, - "(current) NT password: ", + _("(current) NT password: "), NULL, (const char **) &pass_old); TALLOC_FREE(Announce); @@ -2976,8 +3001,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, ret = _winbind_read_password(ctx, lctrl, NULL, - "Enter new NT password: ", - "Retype new NT password: ", + _("Enter new NT password: "), + _("Retype new NT password: "), (const char **)&pass_new); if (ret != PAM_SUCCESS) { diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h index cb6f450ccb..0656f5972e 100644 --- a/source3/nsswitch/pam_winbind.h +++ b/source3/nsswitch/pam_winbind.h @@ -9,6 +9,7 @@ #include "system/time.h" #include <talloc.h> #include "libwbclient/wbclient.h" +#include "localedir.h" #define MODULE_NAME "pam_winbind" #define PAM_SM_AUTH @@ -22,6 +23,10 @@ #include <iniparser.h> +#ifdef HAVE_LIBINTL_H +#include <libintl.h> +#endif + #ifndef LINUX /* Solaris always uses dynamic pam modules */ @@ -101,12 +106,20 @@ do { \ #define WINBIND_WARN_PWD_EXPIRE 0x00002000 #define WINBIND_MKHOMEDIR 0x00004000 +#if defined(HAVE_GETTEXT) && !defined(__LCLINT__) +#define _(string) dgettext(MODULE_NAME, string) +#else +#define _(string) string +#endif + +#define N_(string) string + /* * here is the string to inform the user that the new passwords they * typed were not the same. */ -#define MISTYPED_PASS "Sorry, passwords do not match" +#define MISTYPED_PASS _("Sorry, passwords do not match") #define on(x, y) (x & y) #define off(x, y) (!(x & y)) diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c index 6e6d2bbbf8..a1646215bd 100644 --- a/source3/nsswitch/wb_common.c +++ b/source3/nsswitch/wb_common.c @@ -314,7 +314,7 @@ static int winbind_open_pipe_sock(int recursing, int need_priv) if ((need_priv != 0) && (is_privileged == 0)) { winbind_close_sock(); } - + if (winbindd_fd != -1) { return winbindd_fd; } diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 84f01e19ff..d14cfe94b7 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -75,7 +75,7 @@ static char winbind_separator_int(bool strict) /* HACK: (this module should not call lp_ funtions) */ sep = *lp_winbind_separator(); } - + return sep; } @@ -130,6 +130,31 @@ static bool parse_wbinfo_domain_user(const char *domuser, fstring domain, return true; } +/* Parse string of "uid,sid" or "gid,sid" into separate int and string values. + * Return true if input was valid, false otherwise. */ +static bool parse_mapping_arg(char *arg, int *id, char **sid) +{ + char *tmp, *endptr; + + if (!arg || !*arg) + return false; + + tmp = strtok(arg, ","); + *sid = strtok(NULL, ","); + + if (!tmp || !*tmp || !*sid || !**sid) + return false; + + /* Because atoi() can return 0 on invalid input, which would be a valid + * UID/GID we must use strtol() and do error checking */ + *id = strtol(tmp, &endptr, 10); + + if (endptr[0] != '\0') + return false; + + return true; +} + /* pull pwent info for a given user */ static bool wbinfo_get_userinfo(char *user) @@ -738,6 +763,102 @@ static bool wbinfo_allocate_gid(void) return true; } +static bool wbinfo_set_uid_mapping(uid_t uid, const char *sid_str) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcDomainSid sid; + + /* Send request */ + + wbc_status = wbcStringToSid(sid_str, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } + + wbc_status = wbcSetUidMapping(uid, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } + + /* Display response */ + + d_printf("uid %d now mapped to sid %s\n", uid, sid_str); + + return true; +} + +static bool wbinfo_set_gid_mapping(gid_t gid, const char *sid_str) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcDomainSid sid; + + /* Send request */ + + wbc_status = wbcStringToSid(sid_str, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } + + wbc_status = wbcSetGidMapping(gid, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } + + /* Display response */ + + d_printf("gid %d now mapped to sid %s\n", gid, sid_str); + + return true; +} + +static bool wbinfo_remove_uid_mapping(uid_t uid, const char *sid_str) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcDomainSid sid; + + /* Send request */ + + wbc_status = wbcStringToSid(sid_str, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } + + wbc_status = wbcRemoveUidMapping(uid, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } + + /* Display response */ + + d_printf("Removed uid %d to sid %s mapping\n", uid, sid_str); + + return true; +} + +static bool wbinfo_remove_gid_mapping(gid_t gid, const char *sid_str) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcDomainSid sid; + + /* Send request */ + + wbc_status = wbcStringToSid(sid_str, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } + + wbc_status = wbcRemoveGidMapping(gid, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } + + /* Display response */ + + d_printf("Removed gid %d to sid %s mapping\n", gid, sid_str); + + return true; +} + /* Convert sid to string */ static bool wbinfo_lookupsid(const char *sid_str) @@ -1414,6 +1535,10 @@ enum { OPT_USERSIDS, OPT_ALLOCATE_UID, OPT_ALLOCATE_GID, + OPT_SET_UID_MAPPING, + OPT_SET_GID_MAPPING, + OPT_REMOVE_UID_MAPPING, + OPT_REMOVE_GID_MAPPING, OPT_SEPARATOR, OPT_LIST_ALL_DOMAINS, OPT_LIST_OWN_DOMAIN, @@ -1431,8 +1556,10 @@ int main(int argc, char **argv, char **envp) TALLOC_CTX *frame = talloc_stackframe(); poptContext pc; static char *string_arg; + char *string_subarg = NULL; static char *opt_domain_name; static int int_arg; + int int_subarg = -1; int result = 1; bool verbose = false; @@ -1459,6 +1586,10 @@ int main(int argc, char **argv, char **envp) "Get a new UID out of idmap" }, { "allocate-gid", 0, POPT_ARG_NONE, 0, OPT_ALLOCATE_GID, "Get a new GID out of idmap" }, + { "set-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_UID_MAPPING, "Create or modify uid to sid mapping in idmap", "UID,SID" }, + { "set-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_GID_MAPPING, "Create or modify gid to sid mapping in idmap", "GID,SID" }, + { "remove-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_UID_MAPPING, "Remove uid to sid mapping in idmap", "UID,SID" }, + { "remove-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_GID_MAPPING, "Remove gid to sid mapping in idmap", "GID,SID" }, { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" }, { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" }, { "all-domains", 0, POPT_ARG_NONE, 0, OPT_LIST_ALL_DOMAINS, "List all domains (trusted and own domain)" }, @@ -1473,7 +1604,7 @@ int main(int argc, char **argv, char **envp) { "user-domgroups", 0, POPT_ARG_STRING, &string_arg, OPT_USERDOMGROUPS, "Get user domain groups", "SID" }, { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" }, - { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" }, + { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" }, { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" }, { "getdcname", 0, POPT_ARG_STRING, &string_arg, OPT_GETDCNAME, "Get a DC name for a foreign domain", "domainname" }, @@ -1482,7 +1613,7 @@ int main(int argc, char **argv, char **envp) { "ping", 'p', POPT_ARG_NONE, 0, 'p', "Ping winbindd to see if it is alive" }, { "domain", 0, POPT_ARG_STRING, &opt_domain_name, OPT_DOMAIN_NAME, "Define to the domain to restrict operation", "domain" }, #ifdef WITH_FAKE_KASERVER - { "klog", 'k', POPT_ARG_STRING, &string_arg, 'k', "set an AFS token from winbind", "user%password" }, + { "klog", 'k', POPT_ARG_STRING, &string_arg, 'k', "set an AFS token from winbind", "user%password" }, #endif #ifdef HAVE_KRB5 { "krb5auth", 'K', POPT_ARG_STRING, &string_arg, 'K', "authenticate user using Kerberos", "user%password" }, @@ -1534,7 +1665,7 @@ int main(int argc, char **argv, char **envp) load_interfaces(); - pc = poptGetContext(NULL, argc, (const char **)argv, long_options, + pc = poptGetContext(NULL, argc, (const char **)argv, long_options, POPT_CONTEXT_KEEP_FIRST); while((opt = poptGetNextOpt(pc)) != -1) { @@ -1627,6 +1758,48 @@ int main(int argc, char **argv, char **envp) goto done; } break; + case OPT_SET_UID_MAPPING: + if (!parse_mapping_arg(string_arg, &int_subarg, + &string_subarg) || + !wbinfo_set_uid_mapping(int_subarg, string_subarg)) + { + d_fprintf(stderr, "Could not create or modify " + "uid to sid mapping\n"); + goto done; + } + break; + case OPT_SET_GID_MAPPING: + if (!parse_mapping_arg(string_arg, &int_subarg, + &string_subarg) || + !wbinfo_set_gid_mapping(int_subarg, string_subarg)) + { + d_fprintf(stderr, "Could not create or modify " + "gid to sid mapping\n"); + goto done; + } + break; + case OPT_REMOVE_UID_MAPPING: + if (!parse_mapping_arg(string_arg, &int_subarg, + &string_subarg) || + !wbinfo_remove_uid_mapping(int_subarg, + string_subarg)) + { + d_fprintf(stderr, "Could not remove uid to sid " + "mapping\n"); + goto done; + } + break; + case OPT_REMOVE_GID_MAPPING: + if (!parse_mapping_arg(string_arg, &int_subarg, + &string_subarg) || + !wbinfo_remove_gid_mapping(int_subarg, + string_subarg)) + { + d_fprintf(stderr, "Could not remove gid to sid " + "mapping\n"); + goto done; + } + break; case 't': if (!wbinfo_check_secret()) { d_fprintf(stderr, "Could not check secret\n"); diff --git a/source3/nsswitch/winbind_struct_protocol.h b/source3/nsswitch/winbind_struct_protocol.h index ff52dbddaf..36873f2096 100644 --- a/source3/nsswitch/winbind_struct_protocol.h +++ b/source3/nsswitch/winbind_struct_protocol.h @@ -41,7 +41,9 @@ /* Update this when you change the interface. */ -#define WINBIND_INTERFACE_VERSION 19 +/* Version 20: added WINBINDD_REMOVE_MAPPING command */ + +#define WINBIND_INTERFACE_VERSION 20 /* Have to deal with time_t being 4 or 8 bytes due to structure alignment. On a 64bit Linux box, we have to support a constant structure size @@ -95,7 +97,7 @@ enum winbindd_cmd { /* Lookup functions */ - WINBINDD_SID_TO_UID, + WINBINDD_SID_TO_UID, WINBINDD_SID_TO_GID, WINBINDD_SIDS_TO_XIDS, WINBINDD_UID_TO_SID, @@ -104,6 +106,7 @@ enum winbindd_cmd { WINBINDD_ALLOCATE_UID, WINBINDD_ALLOCATE_GID, WINBINDD_SET_MAPPING, + WINBINDD_REMOVE_MAPPING, WINBINDD_SET_HWM, /* Miscellaneous other stuff */ @@ -150,6 +153,7 @@ enum winbindd_cmd { WINBINDD_DUAL_UID2SID, WINBINDD_DUAL_GID2SID, WINBINDD_DUAL_SET_MAPPING, + WINBINDD_DUAL_REMOVE_MAPPING, WINBINDD_DUAL_SET_HWM, /* Wrapper around possibly blocking unix nss calls */ @@ -202,7 +206,9 @@ typedef struct winbindd_gr { #define WBFLAG_IS_PRIVILEGED 0x00000400 /* not used */ /* Flag to say this is a winbindd internal send - don't recurse. */ #define WBFLAG_RECURSE 0x00000800 - +/* Flag to tell winbind the NTLMv2 blob is too big for the struct and is in the + * extra_data field */ +#define WBFLAG_BIG_NTLMV2_BLOB 0x00010000 #define WINBINDD_MAX_EXTRA_DATA (128*1024) diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c index 2f82997aaf..e028eb8cf2 100644 --- a/source3/nsswitch/wins.c +++ b/source3/nsswitch/wins.c @@ -24,6 +24,14 @@ #include <ns_daemon.h> #endif +#if HAVE_PTHREAD_H +#include <pthread.h> +#endif + +#if HAVE_PTHREAD +static pthread_mutex_t wins_nss_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + #ifndef INADDRSZ #define INADDRSZ 4 #endif @@ -320,11 +328,16 @@ NSS_STATUS _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, char *buffer, size_t buflen, int *h_errnop) { + NSS_STATUS nss_status = NSS_STATUS_SUCCESS; struct in_addr *ip_list; int i, count; fstring name; size_t namelen; +#if HAVE_PTHREAD + pthread_mutex_lock(&wins_nss_mutex); +#endif + memset(he, '\0', sizeof(*he)); fstrcpy(name, hostname); @@ -332,8 +345,10 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, ip_list = lookup_byname_backend(name, &count); - if (!ip_list) - return NSS_STATUS_NOTFOUND; + if (!ip_list) { + nss_status = NSS_STATUS_NOTFOUND; + goto out; + } /* Copy h_name */ @@ -341,7 +356,8 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, if ((he->h_name = get_static(&buffer, &buflen, namelen)) == NULL) { free(ip_list); - return NSS_STATUS_TRYAGAIN; + nss_status = NSS_STATUS_TRYAGAIN; + goto out; } memcpy(he->h_name, name, namelen); @@ -353,20 +369,23 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, if (get_static(&buffer, &buflen, i) == NULL) { free(ip_list); - return NSS_STATUS_TRYAGAIN; + nss_status = NSS_STATUS_TRYAGAIN; + goto out; } if ((he->h_addr_list = (char **)get_static( &buffer, &buflen, (count + 1) * sizeof(char *))) == NULL) { free(ip_list); - return NSS_STATUS_TRYAGAIN; + nss_status = NSS_STATUS_TRYAGAIN; + goto out; } for (i = 0; i < count; i++) { if ((he->h_addr_list[i] = get_static(&buffer, &buflen, INADDRSZ)) == NULL) { free(ip_list); - return NSS_STATUS_TRYAGAIN; + nss_status = NSS_STATUS_TRYAGAIN; + goto out; } memcpy(he->h_addr_list[i], &ip_list[i], INADDRSZ); } @@ -385,16 +404,27 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, if ((i = (unsigned long)(buffer) % sizeof(char*)) != 0) i = sizeof(char*) - i; - if (get_static(&buffer, &buflen, i) == NULL) - return NSS_STATUS_TRYAGAIN; + if (get_static(&buffer, &buflen, i) == NULL) { + nss_status = NSS_STATUS_TRYAGAIN; + goto out; + } if ((he->h_aliases = (char **)get_static( - &buffer, &buflen, sizeof(char *))) == NULL) - return NSS_STATUS_TRYAGAIN; + &buffer, &buflen, sizeof(char *))) == NULL) { + nss_status = NSS_STATUS_TRYAGAIN; + goto out; + } he->h_aliases[0] = NULL; - return NSS_STATUS_SUCCESS; + nss_status = NSS_STATUS_SUCCESS; + + out: + +#if HAVE_PTHREAD + pthread_mutex_unlock(&wins_nss_mutex); +#endif + return nss_status; } @@ -402,12 +432,15 @@ NSS_STATUS _nss_wins_gethostbyname2_r(const char *name, int af, struct hostent *he, char *buffer, size_t buflen, int *h_errnop) { + NSS_STATUS nss_status; + if(af!=AF_INET) { *h_errnop = NO_DATA; - return NSS_STATUS_UNAVAIL; + nss_status = NSS_STATUS_UNAVAIL; + } else { + nss_status = _nss_wins_gethostbyname_r( + name, he, buffer, buflen, h_errnop); } - - return _nss_wins_gethostbyname_r( - name, he, buffer, buflen, h_errnop); + return nss_status; } #endif |