diff options
Diffstat (limited to 'source3/nsswitch/libwbclient')
-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 |
5 files changed, 430 insertions, 12 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 */ |