summaryrefslogtreecommitdiff
path: root/source3/nsswitch/libwbclient
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch/libwbclient')
-rw-r--r--source3/nsswitch/libwbclient/wbc_idmap.c154
-rw-r--r--source3/nsswitch/libwbclient/wbc_pam.c15
-rw-r--r--source3/nsswitch/libwbclient/wbc_pwd.c216
-rw-r--r--source3/nsswitch/libwbclient/wbclient.c2
-rw-r--r--source3/nsswitch/libwbclient/wbclient.h55
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
*/