mirror of
https://github.com/samba-team/samba.git
synced 2025-02-23 09:57:40 +03:00
libwbclient: Separate out the async functions
This commit is contained in:
parent
613777e6dc
commit
b99d9f86e4
@ -1,15 +1,24 @@
|
||||
[SUBSYSTEM::LIBWBCLIENT]
|
||||
PUBLIC_DEPENDENCIES = LIBASYNC_REQ \
|
||||
LIBTEVENT \
|
||||
LIBTALLOC \
|
||||
UTIL_TEVENT
|
||||
PUBLIC_DEPENDENCIES = LIBTALLOC
|
||||
|
||||
LIBWBCLIENT_OBJ_FILES = $(addprefix $(libwbclientsrcdir)/, wbc_async.o \
|
||||
wbc_guid.o \
|
||||
LIBWBCLIENT_OBJ_FILES = $(addprefix $(libwbclientsrcdir)/, wbc_guid.o \
|
||||
wbc_idmap.o \
|
||||
wbclient.o \
|
||||
wbc_pam.o \
|
||||
wbc_pwd.o \
|
||||
wbc_sid.o \
|
||||
wbc_util.o \
|
||||
wbc_util.o )
|
||||
|
||||
[SUBSYSTEM::LIBWBCLIENT_ASYNC]
|
||||
PUBLIC_DEPENDENCIES = LIBASYNC_REQ \
|
||||
LIBTEVENT \
|
||||
LIBTALLOC \
|
||||
UTIL_TEVENT \
|
||||
LIBWBCLIENT
|
||||
|
||||
LIBWBCLIENT_ASYNC_OBJ_FILES = $(addprefix $(libwbclientsrcdir)/, wbc_async.o \
|
||||
wbc_idmap_async.o \
|
||||
wbc_pam_async.o \
|
||||
wbc_sid_async.o \
|
||||
wbc_util_async.o \
|
||||
wb_reqtrans.o )
|
||||
|
@ -4,8 +4,6 @@
|
||||
Winbind client API
|
||||
|
||||
Copyright (C) Gerald (Jerry) Carter 2007
|
||||
Copyright (C) Kai Blin 2009
|
||||
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@ -26,105 +24,6 @@
|
||||
#include "replace.h"
|
||||
#include "libwbclient.h"
|
||||
|
||||
struct wbc_sid_to_uid_state {
|
||||
struct winbindd_request req;
|
||||
uid_t uid;
|
||||
};
|
||||
|
||||
static void wbcSidToUid_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Convert a Windows SID to a Unix uid, allocating an uid if needed
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev tevent context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
* @param *sid pointer to the domain SID to be resolved
|
||||
*
|
||||
* @return tevent_req on success, NULL on error
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcSidToUid_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
const struct wbcDomainSid *sid)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_sid_to_uid_state *state;
|
||||
char *sid_string;
|
||||
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_sid_to_uid_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_SID_TO_UID;
|
||||
wbc_status = wbcSidToString(sid, &sid_string);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
strncpy(state->req.data.sid, sid_string, sizeof(state->req.data.sid)-1);
|
||||
wbcFreeMemory(sid_string);
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcSidToUid_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcSidToUid_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_sid_to_uid_state *state = tevent_req_data(
|
||||
req, struct wbc_sid_to_uid_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->uid = resp->data.uid;
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a Unix uid mapped to a Windows SID
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param *puid pointer to hold the resolved uid_t value
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcSidToUid_recv(struct tevent_req *req, uid_t *puid)
|
||||
{
|
||||
struct wbc_sid_to_uid_state *state = tevent_req_data(
|
||||
req, struct wbc_sid_to_uid_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*puid = state->uid;
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/* Convert a Windows SID to a Unix uid, allocating an uid if needed */
|
||||
wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid)
|
||||
{
|
||||
@ -171,116 +70,6 @@ wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid,
|
||||
return WBC_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
struct wbc_uid_to_sid_state {
|
||||
struct winbindd_request req;
|
||||
struct wbcDomainSid *sid;
|
||||
};
|
||||
|
||||
static void wbcUidToSid_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request a Windows SID for an Unix uid, allocating an SID if needed
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev tevent context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
* @param uid uid to be resolved to a SID
|
||||
*
|
||||
* @return tevent_req on success, NULL on error
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcUidToSid_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
uid_t uid)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_uid_to_sid_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_uid_to_sid_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_UID_TO_SID;
|
||||
state->req.data.uid = uid;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcUidToSid_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcUidToSid_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_uid_to_sid_state *state = tevent_req_data(
|
||||
req, struct wbc_uid_to_sid_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
state->sid = talloc(state, struct wbcDomainSid);
|
||||
if (state->sid == NULL) {
|
||||
TALLOC_FREE(resp);
|
||||
tevent_req_error(req, WBC_ERR_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
wbc_status = wbcStringToSid(resp->data.sid.sid, state->sid);
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a Unix uid mapped to a Windows SID
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param *psid pointer to hold the resolved SID
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcUidToSid_recv(struct tevent_req *req, struct wbcDomainSid *psid)
|
||||
{
|
||||
struct wbc_uid_to_sid_state *state = tevent_req_data(
|
||||
req, struct wbc_uid_to_sid_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (psid == NULL) {
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
memcpy(psid, state->sid, sizeof(struct wbcDomainSid));
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/* Convert a Unix uid to a Windows SID, allocating a SID if needed */
|
||||
wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid)
|
||||
{
|
||||
@ -321,106 +110,6 @@ wbcErr wbcQueryUidToSid(uid_t uid,
|
||||
return WBC_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
struct wbc_sid_to_gid_state {
|
||||
struct winbindd_request req;
|
||||
gid_t gid;
|
||||
};
|
||||
|
||||
static void wbcSidToGid_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request to convert a Windows SID to a Unix gid,
|
||||
* allocating a gid if needed
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev tevent context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
* @param *sid pointer to the domain SID to be resolved
|
||||
*
|
||||
* @return tevent_req on success, NULL on error
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcSidToGid_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
const struct wbcDomainSid *sid)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_sid_to_gid_state *state;
|
||||
char *sid_string;
|
||||
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_sid_to_gid_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_SID_TO_GID;
|
||||
wbc_status = wbcSidToString(sid, &sid_string);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
strncpy(state->req.data.sid, sid_string, sizeof(state->req.data.sid)-1);
|
||||
wbcFreeMemory(sid_string);
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcSidToGid_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcSidToGid_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_sid_to_gid_state *state = tevent_req_data(
|
||||
req, struct wbc_sid_to_gid_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->gid = resp->data.gid;
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a Unix gid mapped to a Windows SID
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param *pgid pointer to hold the resolved gid_t value
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcSidToGid_recv(struct tevent_req *req, gid_t *pgid)
|
||||
{
|
||||
struct wbc_sid_to_gid_state *state = tevent_req_data(
|
||||
req, struct wbc_sid_to_gid_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*pgid = state->gid;
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/** @brief Convert a Windows SID to a Unix gid, allocating a gid if needed
|
||||
*
|
||||
* @param *sid Pointer to the domain SID to be resolved
|
||||
@ -477,116 +166,6 @@ wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid,
|
||||
return WBC_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
struct wbc_gid_to_sid_state {
|
||||
struct winbindd_request req;
|
||||
struct wbcDomainSid *sid;
|
||||
};
|
||||
|
||||
static void wbcGidToSid_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request a Windows SID for an Unix Gid, allocating an SID if needed
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev tevent context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
* @param gid gid to be resolved to a SID
|
||||
*
|
||||
* @return tevent_req on success, NULL on error
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcGidToSid_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
gid_t gid)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_gid_to_sid_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_gid_to_sid_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_GID_TO_SID;
|
||||
state->req.data.gid = gid;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcGidToSid_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcGidToSid_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_gid_to_sid_state *state = tevent_req_data(
|
||||
req, struct wbc_gid_to_sid_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
state->sid = talloc(state, struct wbcDomainSid);
|
||||
if (state->sid == NULL) {
|
||||
TALLOC_FREE(resp);
|
||||
tevent_req_error(req, WBC_ERR_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
wbc_status = wbcStringToSid(resp->data.sid.sid, state->sid);
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a Unix gid mapped to a Windows SID
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param *psid pointer to hold the resolved SID
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcGidToSid_recv(struct tevent_req *req, struct wbcDomainSid *psid)
|
||||
{
|
||||
struct wbc_gid_to_sid_state *state = tevent_req_data(
|
||||
req, struct wbc_gid_to_sid_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (psid == NULL) {
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
memcpy(psid, state->sid, sizeof(struct wbcDomainSid));
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Convert a Unix gid to a Windows SID, allocating a SID if needed */
|
||||
wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid)
|
||||
|
447
nsswitch/libwbclient/wbc_idmap_async.c
Normal file
447
nsswitch/libwbclient/wbc_idmap_async.c
Normal file
@ -0,0 +1,447 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Winbind client API
|
||||
|
||||
Copyright (C) 2009,2010 Kai Blin <kai@samba.org>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Required Headers */
|
||||
|
||||
#include "replace.h"
|
||||
#include "libwbclient.h"
|
||||
|
||||
struct wbc_sid_to_uid_state {
|
||||
struct winbindd_request req;
|
||||
uid_t uid;
|
||||
};
|
||||
|
||||
static void wbcSidToUid_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Convert a Windows SID to a Unix uid, allocating an uid if needed
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev tevent context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
* @param *sid pointer to the domain SID to be resolved
|
||||
*
|
||||
* @return tevent_req on success, NULL on error
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcSidToUid_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
const struct wbcDomainSid *sid)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_sid_to_uid_state *state;
|
||||
char *sid_string;
|
||||
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_sid_to_uid_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_SID_TO_UID;
|
||||
wbc_status = wbcSidToString(sid, &sid_string);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
strncpy(state->req.data.sid, sid_string, sizeof(state->req.data.sid)-1);
|
||||
wbcFreeMemory(sid_string);
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcSidToUid_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcSidToUid_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_sid_to_uid_state *state = tevent_req_data(
|
||||
req, struct wbc_sid_to_uid_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->uid = resp->data.uid;
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a Unix uid mapped to a Windows SID
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param *puid pointer to hold the resolved uid_t value
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcSidToUid_recv(struct tevent_req *req, uid_t *puid)
|
||||
{
|
||||
struct wbc_sid_to_uid_state *state = tevent_req_data(
|
||||
req, struct wbc_sid_to_uid_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*puid = state->uid;
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
struct wbc_uid_to_sid_state {
|
||||
struct winbindd_request req;
|
||||
struct wbcDomainSid *sid;
|
||||
};
|
||||
|
||||
static void wbcUidToSid_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request a Windows SID for an Unix uid, allocating an SID if needed
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev tevent context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
* @param uid uid to be resolved to a SID
|
||||
*
|
||||
* @return tevent_req on success, NULL on error
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcUidToSid_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
uid_t uid)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_uid_to_sid_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_uid_to_sid_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_UID_TO_SID;
|
||||
state->req.data.uid = uid;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcUidToSid_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcUidToSid_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_uid_to_sid_state *state = tevent_req_data(
|
||||
req, struct wbc_uid_to_sid_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
state->sid = talloc(state, struct wbcDomainSid);
|
||||
if (state->sid == NULL) {
|
||||
TALLOC_FREE(resp);
|
||||
tevent_req_error(req, WBC_ERR_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
wbc_status = wbcStringToSid(resp->data.sid.sid, state->sid);
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a Unix uid mapped to a Windows SID
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param *psid pointer to hold the resolved SID
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcUidToSid_recv(struct tevent_req *req, struct wbcDomainSid *psid)
|
||||
{
|
||||
struct wbc_uid_to_sid_state *state = tevent_req_data(
|
||||
req, struct wbc_uid_to_sid_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (psid == NULL) {
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
memcpy(psid, state->sid, sizeof(struct wbcDomainSid));
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
struct wbc_sid_to_gid_state {
|
||||
struct winbindd_request req;
|
||||
gid_t gid;
|
||||
};
|
||||
|
||||
static void wbcSidToGid_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request to convert a Windows SID to a Unix gid,
|
||||
* allocating a gid if needed
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev tevent context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
* @param *sid pointer to the domain SID to be resolved
|
||||
*
|
||||
* @return tevent_req on success, NULL on error
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcSidToGid_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
const struct wbcDomainSid *sid)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_sid_to_gid_state *state;
|
||||
char *sid_string;
|
||||
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_sid_to_gid_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_SID_TO_GID;
|
||||
wbc_status = wbcSidToString(sid, &sid_string);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
strncpy(state->req.data.sid, sid_string, sizeof(state->req.data.sid)-1);
|
||||
wbcFreeMemory(sid_string);
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcSidToGid_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcSidToGid_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_sid_to_gid_state *state = tevent_req_data(
|
||||
req, struct wbc_sid_to_gid_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->gid = resp->data.gid;
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a Unix gid mapped to a Windows SID
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param *pgid pointer to hold the resolved gid_t value
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcSidToGid_recv(struct tevent_req *req, gid_t *pgid)
|
||||
{
|
||||
struct wbc_sid_to_gid_state *state = tevent_req_data(
|
||||
req, struct wbc_sid_to_gid_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*pgid = state->gid;
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
struct wbc_gid_to_sid_state {
|
||||
struct winbindd_request req;
|
||||
struct wbcDomainSid *sid;
|
||||
};
|
||||
|
||||
static void wbcGidToSid_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request a Windows SID for an Unix Gid, allocating an SID if needed
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev tevent context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
* @param gid gid to be resolved to a SID
|
||||
*
|
||||
* @return tevent_req on success, NULL on error
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcGidToSid_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
gid_t gid)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_gid_to_sid_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_gid_to_sid_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_GID_TO_SID;
|
||||
state->req.data.gid = gid;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcGidToSid_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcGidToSid_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_gid_to_sid_state *state = tevent_req_data(
|
||||
req, struct wbc_gid_to_sid_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
state->sid = talloc(state, struct wbcDomainSid);
|
||||
if (state->sid == NULL) {
|
||||
TALLOC_FREE(resp);
|
||||
tevent_req_error(req, WBC_ERR_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
wbc_status = wbcStringToSid(resp->data.sid.sid, state->sid);
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a Unix gid mapped to a Windows SID
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param *psid pointer to hold the resolved SID
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcGidToSid_recv(struct tevent_req *req, struct wbcDomainSid *psid)
|
||||
{
|
||||
struct wbc_gid_to_sid_state *state = tevent_req_data(
|
||||
req, struct wbc_gid_to_sid_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (psid == NULL) {
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
memcpy(psid, state->sid, sizeof(struct wbcDomainSid));
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
@ -300,275 +300,6 @@ done:
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
struct wbc_authenticate_user_ex_state {
|
||||
struct winbindd_request req;
|
||||
struct tevent_context *ev;
|
||||
struct wb_context *wb_ctx;
|
||||
const struct wbcAuthUserParams *params;
|
||||
struct wbcAuthUserInfo *info;
|
||||
struct wbcAuthErrorInfo *error;
|
||||
};
|
||||
|
||||
static void wbcAuthenticateUserEx_got_info(struct tevent_req *subreq);
|
||||
static void wbcAuthenticateUserEx_done(struct tevent_req *subreq);
|
||||
|
||||
struct tevent_req *wbcAuthenticateUserEx_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
const struct wbcAuthUserParams *params)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_authenticate_user_ex_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct wbc_authenticate_user_ex_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->ev = ev;
|
||||
state->wb_ctx = wb_ctx;
|
||||
state->params = params;
|
||||
|
||||
if (!params) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
if (!params->account_name) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
if (params->flags) {
|
||||
state->req.flags = params->flags;
|
||||
}
|
||||
|
||||
switch (params->level) {
|
||||
case WBC_AUTH_USER_LEVEL_PLAIN:
|
||||
state->req.cmd = WINBINDD_PAM_AUTH;
|
||||
state->req.flags |= WBFLAG_PAM_INFO3_TEXT |
|
||||
WBFLAG_PAM_USER_SESSION_KEY |
|
||||
WBFLAG_PAM_LMKEY;
|
||||
|
||||
if (!params->password.plaintext) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
strncpy(state->req.data.auth.pass,
|
||||
params->password.plaintext,
|
||||
sizeof(state->req.data.auth.pass)-1);
|
||||
|
||||
if (params->domain_name && params->domain_name[0]) {
|
||||
/* We need to get the winbind separator :-( */
|
||||
subreq = wbcInfo_send(state, ev, wb_ctx);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq,
|
||||
wbcAuthenticateUserEx_got_info,
|
||||
req);
|
||||
return req;
|
||||
} else {
|
||||
strncpy(state->req.data.auth.user,
|
||||
params->account_name,
|
||||
sizeof(state->req.data.auth.user)-1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case WBC_AUTH_USER_LEVEL_HASH:
|
||||
tevent_req_error(req, WBC_ERR_NOT_IMPLEMENTED);
|
||||
return tevent_req_post(req, ev);
|
||||
/* Make some static code checkers happy */
|
||||
break;
|
||||
|
||||
case WBC_AUTH_USER_LEVEL_RESPONSE:
|
||||
state->req.cmd = WINBINDD_PAM_AUTH_CRAP;
|
||||
state->req.flags |= WBFLAG_PAM_INFO3_TEXT |
|
||||
WBFLAG_PAM_USER_SESSION_KEY |
|
||||
WBFLAG_PAM_LMKEY;
|
||||
|
||||
if (params->password.response.lm_length &&
|
||||
!params->password.response.lm_data) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
if (params->password.response.lm_length == 0 &&
|
||||
params->password.response.lm_data) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
if (params->password.response.nt_length &&
|
||||
!params->password.response.nt_data) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
if (params->password.response.nt_length == 0&&
|
||||
params->password.response.nt_data) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
strncpy(state->req.data.auth_crap.user,
|
||||
params->account_name,
|
||||
sizeof(state->req.data.auth_crap.user)-1);
|
||||
if (params->domain_name) {
|
||||
strncpy(state->req.data.auth_crap.domain,
|
||||
params->domain_name,
|
||||
sizeof(state->req.data.auth_crap.domain)-1);
|
||||
}
|
||||
if (params->workstation_name) {
|
||||
strncpy(state->req.data.auth_crap.workstation,
|
||||
params->workstation_name,
|
||||
sizeof(state->req.data.auth_crap.workstation)-1);
|
||||
}
|
||||
|
||||
state->req.data.auth_crap.logon_parameters =
|
||||
params->parameter_control;
|
||||
|
||||
memcpy(state->req.data.auth_crap.chal,
|
||||
params->password.response.challenge,
|
||||
sizeof(state->req.data.auth_crap.chal));
|
||||
|
||||
state->req.data.auth_crap.lm_resp_len =
|
||||
MIN(params->password.response.lm_length,
|
||||
sizeof(state->req.data.auth_crap.lm_resp));
|
||||
state->req.data.auth_crap.nt_resp_len =
|
||||
MIN(params->password.response.nt_length,
|
||||
sizeof(state->req.data.auth_crap.nt_resp));
|
||||
if (params->password.response.lm_data) {
|
||||
memcpy(state->req.data.auth_crap.lm_resp,
|
||||
params->password.response.lm_data,
|
||||
state->req.data.auth_crap.lm_resp_len);
|
||||
}
|
||||
if (params->password.response.nt_data) {
|
||||
memcpy(state->req.data.auth_crap.nt_resp,
|
||||
params->password.response.nt_data,
|
||||
state->req.data.auth_crap.nt_resp_len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
break;
|
||||
}
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcAuthenticateUserEx_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcAuthenticateUserEx_got_info(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_authenticate_user_ex_state *state = tevent_req_data(
|
||||
req, struct wbc_authenticate_user_ex_state);
|
||||
char *version_string;
|
||||
char separator;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wbcInfo_recv(subreq, state, &separator, &version_string);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(state->req.data.auth.user,
|
||||
sizeof(state->req.data.auth.user)-1,
|
||||
"%s%c%s",
|
||||
state->params->domain_name,
|
||||
separator,
|
||||
state->params->account_name);
|
||||
|
||||
subreq = wb_trans_send(state, state->ev, state->wb_ctx, false,
|
||||
&state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcAuthenticateUserEx_done, req);
|
||||
return;
|
||||
}
|
||||
|
||||
static void wbcAuthenticateUserEx_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_authenticate_user_ex_state *state = tevent_req_data(
|
||||
req, struct wbc_authenticate_user_ex_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
ZERO_STRUCT(resp);
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (resp->data.auth.nt_status != 0) {
|
||||
wbc_status = wbc_create_error_info(resp, &state->error);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
tevent_req_error(req, WBC_ERR_AUTH_ERROR);
|
||||
goto done;
|
||||
}
|
||||
|
||||
wbc_status = wbc_create_auth_info(state, resp, &state->info);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
TALLOC_FREE(resp);
|
||||
}
|
||||
|
||||
wbcErr wbcAuthenticateUserEx_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct wbcAuthUserInfo **info,
|
||||
struct wbcAuthErrorInfo **error)
|
||||
{
|
||||
struct wbc_authenticate_user_ex_state *state = tevent_req_data(
|
||||
req, struct wbc_authenticate_user_ex_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (error) {
|
||||
*error = NULL;
|
||||
}
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
if (error) {
|
||||
*error = talloc_steal(mem_ctx, state->error);
|
||||
}
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
if (info) {
|
||||
*info = talloc_steal(mem_ctx, state->info);
|
||||
}
|
||||
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
/* Authenticate with more detailed information */
|
||||
wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params,
|
||||
|
483
nsswitch/libwbclient/wbc_pam_async.c
Normal file
483
nsswitch/libwbclient/wbc_pam_async.c
Normal file
@ -0,0 +1,483 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Winbind client API
|
||||
|
||||
Copyright (C) 2009 Kai Blin <kai@samba.org>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Required Headers */
|
||||
|
||||
#include "replace.h"
|
||||
#include "libwbclient.h"
|
||||
#include "../winbind_client.h"
|
||||
|
||||
/* FIXME: Currently this is still a copy of the same function from wbc_pam.c */
|
||||
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 < WBC_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_ERR_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_ERR_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_ERR_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_ERR_INVALID_RESPONSE;
|
||||
BAIL_ON_WBC_ERROR(wbc_status);
|
||||
}
|
||||
e[0] = '\0';
|
||||
p = &e[1];
|
||||
|
||||
e = strchr(s, ':');
|
||||
if (!e) {
|
||||
wbc_status = WBC_ERR_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_ERR_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;
|
||||
}
|
||||
|
||||
/* FIXME: Currently this is still a copy of the same function from wbc_pam.c */
|
||||
static wbcErr wbc_create_error_info(const struct winbindd_response *resp,
|
||||
struct wbcAuthErrorInfo **_e)
|
||||
{
|
||||
wbcErr wbc_status = WBC_ERR_SUCCESS;
|
||||
struct wbcAuthErrorInfo *e;
|
||||
|
||||
e = talloc(NULL, 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;
|
||||
}
|
||||
|
||||
struct wbc_authenticate_user_ex_state {
|
||||
struct winbindd_request req;
|
||||
struct tevent_context *ev;
|
||||
struct wb_context *wb_ctx;
|
||||
const struct wbcAuthUserParams *params;
|
||||
struct wbcAuthUserInfo *info;
|
||||
struct wbcAuthErrorInfo *error;
|
||||
};
|
||||
|
||||
static void wbcAuthenticateUserEx_got_info(struct tevent_req *subreq);
|
||||
static void wbcAuthenticateUserEx_done(struct tevent_req *subreq);
|
||||
|
||||
struct tevent_req *wbcAuthenticateUserEx_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
const struct wbcAuthUserParams *params)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_authenticate_user_ex_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct wbc_authenticate_user_ex_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->ev = ev;
|
||||
state->wb_ctx = wb_ctx;
|
||||
state->params = params;
|
||||
|
||||
if (!params) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
if (!params->account_name) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
if (params->flags) {
|
||||
state->req.flags = params->flags;
|
||||
}
|
||||
|
||||
switch (params->level) {
|
||||
case WBC_AUTH_USER_LEVEL_PLAIN:
|
||||
state->req.cmd = WINBINDD_PAM_AUTH;
|
||||
state->req.flags |= WBFLAG_PAM_INFO3_TEXT |
|
||||
WBFLAG_PAM_USER_SESSION_KEY |
|
||||
WBFLAG_PAM_LMKEY;
|
||||
|
||||
if (!params->password.plaintext) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
strncpy(state->req.data.auth.pass,
|
||||
params->password.plaintext,
|
||||
sizeof(state->req.data.auth.pass)-1);
|
||||
|
||||
if (params->domain_name && params->domain_name[0]) {
|
||||
/* We need to get the winbind separator :-( */
|
||||
subreq = wbcInfo_send(state, ev, wb_ctx);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq,
|
||||
wbcAuthenticateUserEx_got_info,
|
||||
req);
|
||||
return req;
|
||||
} else {
|
||||
strncpy(state->req.data.auth.user,
|
||||
params->account_name,
|
||||
sizeof(state->req.data.auth.user)-1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case WBC_AUTH_USER_LEVEL_HASH:
|
||||
tevent_req_error(req, WBC_ERR_NOT_IMPLEMENTED);
|
||||
return tevent_req_post(req, ev);
|
||||
/* Make some static code checkers happy */
|
||||
break;
|
||||
|
||||
case WBC_AUTH_USER_LEVEL_RESPONSE:
|
||||
state->req.cmd = WINBINDD_PAM_AUTH_CRAP;
|
||||
state->req.flags |= WBFLAG_PAM_INFO3_TEXT |
|
||||
WBFLAG_PAM_USER_SESSION_KEY |
|
||||
WBFLAG_PAM_LMKEY;
|
||||
|
||||
if (params->password.response.lm_length &&
|
||||
!params->password.response.lm_data) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
if (params->password.response.lm_length == 0 &&
|
||||
params->password.response.lm_data) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
if (params->password.response.nt_length &&
|
||||
!params->password.response.nt_data) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
if (params->password.response.nt_length == 0&&
|
||||
params->password.response.nt_data) {
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
strncpy(state->req.data.auth_crap.user,
|
||||
params->account_name,
|
||||
sizeof(state->req.data.auth_crap.user)-1);
|
||||
if (params->domain_name) {
|
||||
strncpy(state->req.data.auth_crap.domain,
|
||||
params->domain_name,
|
||||
sizeof(state->req.data.auth_crap.domain)-1);
|
||||
}
|
||||
if (params->workstation_name) {
|
||||
strncpy(state->req.data.auth_crap.workstation,
|
||||
params->workstation_name,
|
||||
sizeof(state->req.data.auth_crap.workstation)-1);
|
||||
}
|
||||
|
||||
state->req.data.auth_crap.logon_parameters =
|
||||
params->parameter_control;
|
||||
|
||||
memcpy(state->req.data.auth_crap.chal,
|
||||
params->password.response.challenge,
|
||||
sizeof(state->req.data.auth_crap.chal));
|
||||
|
||||
state->req.data.auth_crap.lm_resp_len =
|
||||
MIN(params->password.response.lm_length,
|
||||
sizeof(state->req.data.auth_crap.lm_resp));
|
||||
state->req.data.auth_crap.nt_resp_len =
|
||||
MIN(params->password.response.nt_length,
|
||||
sizeof(state->req.data.auth_crap.nt_resp));
|
||||
if (params->password.response.lm_data) {
|
||||
memcpy(state->req.data.auth_crap.lm_resp,
|
||||
params->password.response.lm_data,
|
||||
state->req.data.auth_crap.lm_resp_len);
|
||||
}
|
||||
if (params->password.response.nt_data) {
|
||||
memcpy(state->req.data.auth_crap.nt_resp,
|
||||
params->password.response.nt_data,
|
||||
state->req.data.auth_crap.nt_resp_len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
tevent_req_error(req, WBC_ERR_INVALID_PARAM);
|
||||
return tevent_req_post(req, ev);
|
||||
break;
|
||||
}
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcAuthenticateUserEx_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcAuthenticateUserEx_got_info(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_authenticate_user_ex_state *state = tevent_req_data(
|
||||
req, struct wbc_authenticate_user_ex_state);
|
||||
char *version_string;
|
||||
char separator;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wbcInfo_recv(subreq, state, &separator, &version_string);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(state->req.data.auth.user,
|
||||
sizeof(state->req.data.auth.user)-1,
|
||||
"%s%c%s",
|
||||
state->params->domain_name,
|
||||
separator,
|
||||
state->params->account_name);
|
||||
|
||||
subreq = wb_trans_send(state, state->ev, state->wb_ctx, false,
|
||||
&state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcAuthenticateUserEx_done, req);
|
||||
return;
|
||||
}
|
||||
|
||||
static void wbcAuthenticateUserEx_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_authenticate_user_ex_state *state = tevent_req_data(
|
||||
req, struct wbc_authenticate_user_ex_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
ZERO_STRUCT(resp);
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (resp->data.auth.nt_status != 0) {
|
||||
wbc_status = wbc_create_error_info(resp, &state->error);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
tevent_req_error(req, WBC_ERR_AUTH_ERROR);
|
||||
goto done;
|
||||
}
|
||||
|
||||
wbc_status = wbc_create_auth_info(state, resp, &state->info);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
TALLOC_FREE(resp);
|
||||
}
|
||||
|
||||
wbcErr wbcAuthenticateUserEx_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct wbcAuthUserInfo **info,
|
||||
struct wbcAuthErrorInfo **error)
|
||||
{
|
||||
struct wbc_authenticate_user_ex_state *state = tevent_req_data(
|
||||
req, struct wbc_authenticate_user_ex_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (error) {
|
||||
*error = NULL;
|
||||
}
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
if (error) {
|
||||
*error = talloc_steal(mem_ctx, state->error);
|
||||
}
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
if (info) {
|
||||
*info = talloc_steal(mem_ctx, state->info);
|
||||
}
|
||||
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
@ -150,134 +150,6 @@ done:
|
||||
|
||||
}
|
||||
|
||||
struct wbc_lookup_name_state {
|
||||
struct winbindd_request req;
|
||||
struct wb_context *wb_ctx;
|
||||
struct wbcDomainSid *sid;
|
||||
enum wbcSidType name_type;
|
||||
};
|
||||
|
||||
static void wbcLookupName_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request a conversion of a domaind and name to a domain sid
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev tevent context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
* @param *domain Pointer to the domain to be resolved
|
||||
* @param *name Pointer to the name to be resolved
|
||||
*
|
||||
* @return tevent_req on success, NULL on error
|
||||
**/
|
||||
|
||||
struct tevent_req *wbcLookupName_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
const char *domain,
|
||||
const char *name)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_lookup_name_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_lookup_name_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_LOOKUPNAME;
|
||||
strncpy(state->req.data.name.dom_name, domain,
|
||||
sizeof(state->req.data.name.dom_name)-1);
|
||||
strncpy(state->req.data.name.name, name,
|
||||
sizeof(state->req.data.name.name)-1);
|
||||
state->wb_ctx = wb_ctx;
|
||||
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcLookupName_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcLookupName_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_lookup_name_state *state = tevent_req_data(
|
||||
req, struct wbc_lookup_name_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
state->sid = talloc(state, struct wbcDomainSid);
|
||||
if (tevent_req_nomem(state->sid, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
wbc_status = wbcStringToSid(resp->data.sid.sid, state->sid);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
wbcDebug(state->wb_ctx, WBC_DEBUG_ERROR,
|
||||
"wbcStringToSid returned %s!\n",
|
||||
wbcErrorString(wbc_status));
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
state->name_type = (enum wbcSidType)resp->data.sid.type;
|
||||
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a conversion a SID to a domain and name
|
||||
*
|
||||
* @param *
|
||||
* @param *pname Resolved User or group name
|
||||
* @param *pname_type Pointer to the resolved SID type
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcLookupName_recv(struct tevent_req *req,
|
||||
struct wbcDomainSid *sid,
|
||||
enum wbcSidType *name_type)
|
||||
{
|
||||
struct wbc_lookup_name_state *state = tevent_req_data(
|
||||
req, struct wbc_lookup_name_state);
|
||||
wbcErr wbc_status = WBC_ERR_SUCCESS;
|
||||
|
||||
if (!sid || !name_type) {
|
||||
wbcDebug(state->wb_ctx, WBC_DEBUG_TRACE,
|
||||
"Sid is %p, name_type is %p\n", sid, name_type);
|
||||
wbc_status = WBC_ERR_INVALID_PARAM;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
memcpy(sid, state->sid, sizeof(struct wbcDomainSid));
|
||||
*name_type = state->name_type;
|
||||
|
||||
failed:
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
|
||||
/* Convert a domain and name to SID */
|
||||
wbcErr wbcLookupName(const char *domain,
|
||||
@ -322,134 +194,6 @@ wbcErr wbcLookupName(const char *domain,
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
struct wbc_lookup_sid_state {
|
||||
struct winbindd_request req;
|
||||
char *domain;
|
||||
char *name;
|
||||
enum wbcSidType name_type;
|
||||
};
|
||||
|
||||
static void wbcLookupSid_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request a conversion of a SID to a domain and name
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev tevent context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
* @param *sid Pointer to the domain SID to be resolved
|
||||
*
|
||||
* @return tevent_req on success, NULL on error
|
||||
**/
|
||||
|
||||
struct tevent_req *wbcLookupSid_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
const struct wbcDomainSid *sid)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_lookup_sid_state *state;
|
||||
char *sid_string;
|
||||
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_lookup_sid_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_LOOKUPSID;
|
||||
wbc_status = wbcSidToString(sid, &sid_string);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
strncpy(state->req.data.sid, sid_string, sizeof(state->req.data.sid)-1);
|
||||
wbcFreeMemory(sid_string);
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcLookupSid_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcLookupSid_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_lookup_sid_state *state = tevent_req_data(
|
||||
req, struct wbc_lookup_sid_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->domain = talloc_strdup(state, resp->data.name.dom_name);
|
||||
if (tevent_req_nomem(state->domain, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
state->name = talloc_strdup(state, resp->data.name.name);
|
||||
if (tevent_req_nomem(state->name, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
state->name_type = (enum wbcSidType)resp->data.name.type;
|
||||
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a conversion a SID to a domain and name
|
||||
*
|
||||
* @param *mem_ctx, talloc context to move results to
|
||||
* @param *pdomain Resolved Domain name (possibly "")
|
||||
* @param *pname Resolved User or group name
|
||||
* @param *pname_type Pointer to the resolved SID type
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcLookupSid_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
char **pdomain,
|
||||
char **pname,
|
||||
enum wbcSidType *pname_type)
|
||||
{
|
||||
struct wbc_lookup_sid_state *state = tevent_req_data(
|
||||
req, struct wbc_lookup_sid_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
if (pdomain != NULL) {
|
||||
*pdomain = talloc_steal(mem_ctx, state->domain);
|
||||
}
|
||||
|
||||
if (pname != NULL) {
|
||||
*pname = talloc_steal(mem_ctx, state->name);
|
||||
}
|
||||
|
||||
if (pname_type != NULL) {
|
||||
*pname_type = state->name_type;
|
||||
}
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/* Convert a SID to a domain and name */
|
||||
wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
|
||||
|
284
nsswitch/libwbclient/wbc_sid_async.c
Normal file
284
nsswitch/libwbclient/wbc_sid_async.c
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Winbind client API
|
||||
|
||||
Copyright (C) 2009,2010 Kai Blin <kai@samba.org>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Required Headers */
|
||||
|
||||
#include "replace.h"
|
||||
#include "libwbclient.h"
|
||||
#include "../winbind_client.h"
|
||||
|
||||
struct wbc_lookup_name_state {
|
||||
struct winbindd_request req;
|
||||
struct wb_context *wb_ctx;
|
||||
struct wbcDomainSid *sid;
|
||||
enum wbcSidType name_type;
|
||||
};
|
||||
|
||||
static void wbcLookupName_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request a conversion of a domaind and name to a domain sid
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev tevent context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
* @param *domain Pointer to the domain to be resolved
|
||||
* @param *name Pointer to the name to be resolved
|
||||
*
|
||||
* @return tevent_req on success, NULL on error
|
||||
**/
|
||||
|
||||
struct tevent_req *wbcLookupName_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
const char *domain,
|
||||
const char *name)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_lookup_name_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_lookup_name_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_LOOKUPNAME;
|
||||
strncpy(state->req.data.name.dom_name, domain,
|
||||
sizeof(state->req.data.name.dom_name)-1);
|
||||
strncpy(state->req.data.name.name, name,
|
||||
sizeof(state->req.data.name.name)-1);
|
||||
state->wb_ctx = wb_ctx;
|
||||
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcLookupName_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcLookupName_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_lookup_name_state *state = tevent_req_data(
|
||||
req, struct wbc_lookup_name_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
state->sid = talloc(state, struct wbcDomainSid);
|
||||
if (tevent_req_nomem(state->sid, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
wbc_status = wbcStringToSid(resp->data.sid.sid, state->sid);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
wbcDebug(state->wb_ctx, WBC_DEBUG_ERROR,
|
||||
"wbcStringToSid returned %s!\n",
|
||||
wbcErrorString(wbc_status));
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
state->name_type = (enum wbcSidType)resp->data.sid.type;
|
||||
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a conversion a SID to a domain and name
|
||||
*
|
||||
* @param *
|
||||
* @param *pname Resolved User or group name
|
||||
* @param *pname_type Pointer to the resolved SID type
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcLookupName_recv(struct tevent_req *req,
|
||||
struct wbcDomainSid *sid,
|
||||
enum wbcSidType *name_type)
|
||||
{
|
||||
struct wbc_lookup_name_state *state = tevent_req_data(
|
||||
req, struct wbc_lookup_name_state);
|
||||
wbcErr wbc_status = WBC_ERR_SUCCESS;
|
||||
|
||||
if (!sid || !name_type) {
|
||||
wbcDebug(state->wb_ctx, WBC_DEBUG_TRACE,
|
||||
"Sid is %p, name_type is %p\n", sid, name_type);
|
||||
wbc_status = WBC_ERR_INVALID_PARAM;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
memcpy(sid, state->sid, sizeof(struct wbcDomainSid));
|
||||
*name_type = state->name_type;
|
||||
|
||||
failed:
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
|
||||
struct wbc_lookup_sid_state {
|
||||
struct winbindd_request req;
|
||||
char *domain;
|
||||
char *name;
|
||||
enum wbcSidType name_type;
|
||||
};
|
||||
|
||||
static void wbcLookupSid_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request a conversion of a SID to a domain and name
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev tevent context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
* @param *sid Pointer to the domain SID to be resolved
|
||||
*
|
||||
* @return tevent_req on success, NULL on error
|
||||
**/
|
||||
|
||||
struct tevent_req *wbcLookupSid_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
const struct wbcDomainSid *sid)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_lookup_sid_state *state;
|
||||
char *sid_string;
|
||||
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_lookup_sid_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_LOOKUPSID;
|
||||
wbc_status = wbcSidToString(sid, &sid_string);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
strncpy(state->req.data.sid, sid_string, sizeof(state->req.data.sid)-1);
|
||||
wbcFreeMemory(sid_string);
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcLookupSid_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcLookupSid_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_lookup_sid_state *state = tevent_req_data(
|
||||
req, struct wbc_lookup_sid_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->domain = talloc_strdup(state, resp->data.name.dom_name);
|
||||
if (tevent_req_nomem(state->domain, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
state->name = talloc_strdup(state, resp->data.name.name);
|
||||
if (tevent_req_nomem(state->name, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
state->name_type = (enum wbcSidType)resp->data.name.type;
|
||||
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a conversion a SID to a domain and name
|
||||
*
|
||||
* @param *mem_ctx, talloc context to move results to
|
||||
* @param *pdomain Resolved Domain name (possibly "")
|
||||
* @param *pname Resolved User or group name
|
||||
* @param *pname_type Pointer to the resolved SID type
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcLookupSid_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
char **pdomain,
|
||||
char **pname,
|
||||
enum wbcSidType *pname_type)
|
||||
{
|
||||
struct wbc_lookup_sid_state *state = tevent_req_data(
|
||||
req, struct wbc_lookup_sid_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
if (pdomain != NULL) {
|
||||
*pdomain = talloc_steal(mem_ctx, state->domain);
|
||||
}
|
||||
|
||||
if (pname != NULL) {
|
||||
*pname = talloc_steal(mem_ctx, state->name);
|
||||
}
|
||||
|
||||
if (pname_type != NULL) {
|
||||
*pname_type = state->name_type;
|
||||
}
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Winbind client API
|
||||
Winbind client asynchronous API, utility functions
|
||||
|
||||
Copyright (C) Gerald (Jerry) Carter 2007-2008
|
||||
|
||||
@ -25,87 +25,6 @@
|
||||
#include "replace.h"
|
||||
#include "libwbclient.h"
|
||||
|
||||
|
||||
|
||||
struct wbc_ping_state {
|
||||
struct winbindd_request req;
|
||||
};
|
||||
|
||||
static void wbcPing_done(struct tevent_req *subreq);
|
||||
|
||||
/** @brief Ping winbind to see if the service is up and running
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev event context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
*
|
||||
* @return Async request on successful dispatch of the request, NULL on error
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcPing_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_ping_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_ping_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_PING;
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcPing_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcPing_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_ping_state *state = tevent_req_data(
|
||||
req, struct wbc_ping_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/** @brief Receive ping response from winbind
|
||||
*
|
||||
* @param req async request sent in #wbcPing_send
|
||||
*
|
||||
* @return NT_STATUS_OK on success, an error status on error.
|
||||
*/
|
||||
|
||||
wbcErr wbcPing_recv(struct tevent_req *req)
|
||||
{
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/** @brief Ping winbindd to see if the daemon is running
|
||||
*
|
||||
* @return #wbcErr
|
||||
@ -123,595 +42,6 @@ wbcErr wbcPing(void)
|
||||
return wbcRequestResponse(WINBINDD_PING, &request, &response);
|
||||
}
|
||||
|
||||
struct wbc_interface_version_state {
|
||||
struct winbindd_request req;
|
||||
uint32_t version;
|
||||
};
|
||||
|
||||
static void wbcInterfaceVersion_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request the interface version from winbind
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param ev tevent context to use for async requests
|
||||
* @param wb_ctx winbind context
|
||||
*
|
||||
* @return tevevt_req on success, NULL on failure
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcInterfaceVersion_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_interface_version_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_interface_version_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
state->req.cmd = WINBINDD_INTERFACE_VERSION;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInterfaceVersion_done, req);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcInterfaceVersion_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_interface_version_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_version_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->version = resp->data.interface_version;
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive the winbind interface version
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param interface_version pointer to uint32_t to hold the interface
|
||||
* version
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcInterfaceVersion_recv(struct tevent_req *req,
|
||||
uint32_t *interface_version)
|
||||
{
|
||||
struct wbc_interface_version_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_version_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*interface_version = state->version;
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
struct wbc_info_state {
|
||||
struct winbindd_request req;
|
||||
char separator;
|
||||
char *version_string;
|
||||
};
|
||||
|
||||
static void wbcInfo_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request information about the winbind service
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param ev tevent context to use for async requests
|
||||
* @param wb_ctx winbind context
|
||||
*
|
||||
* @return tevent_req on success, NULL on failure
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcInfo_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_info_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_info_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
state->req.cmd = WINBINDD_INFO;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInfo_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcInfo_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_info_state *state = tevent_req_data(
|
||||
req, struct wbc_info_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->version_string = talloc_strdup(state,
|
||||
resp->data.info.samba_version);
|
||||
if (tevent_req_nomem(state->version_string, subreq)) {
|
||||
return;
|
||||
}
|
||||
state->separator = resp->data.info.winbind_separator;
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive information about the running winbind service
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param winbind_separator pointer to a char to hold the separator
|
||||
* @param version_string pointer to a string to hold the version string
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcInfo_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
char *winbind_separator,
|
||||
char **version_string)
|
||||
{
|
||||
struct wbc_info_state *state = tevent_req_data(
|
||||
req, struct wbc_info_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*winbind_separator = state->separator;
|
||||
*version_string = talloc_steal(mem_ctx, state->version_string);
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
struct wbc_netbios_name_state {
|
||||
struct winbindd_request req;
|
||||
char *netbios_name;
|
||||
};
|
||||
|
||||
static void wbcNetbiosName_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request the machine's netbios name
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param ev tevent context to use for async requests
|
||||
* @param wb_ctx winbind context
|
||||
*
|
||||
* @return tevent_req on success, NULL on failure
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcNetbiosName_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_netbios_name_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_netbios_name_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
state->req.cmd = WINBINDD_NETBIOS_NAME;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcNetbiosName_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcNetbiosName_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_netbios_name_state *state = tevent_req_data(
|
||||
req, struct wbc_netbios_name_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->netbios_name = talloc_strdup(state,
|
||||
resp->data.info.samba_version);
|
||||
if (tevent_req_nomem(state->netbios_name, subreq)) {
|
||||
return;
|
||||
}
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive the machine's netbios name
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param netbios_name pointer to a string to hold the netbios name
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcNetbiosName_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
char **netbios_name)
|
||||
{
|
||||
struct wbc_netbios_name_state *state = tevent_req_data(
|
||||
req, struct wbc_netbios_name_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*netbios_name = talloc_steal(mem_ctx, state->netbios_name);
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
struct wbc_domain_name_state {
|
||||
struct winbindd_request req;
|
||||
char *domain_name;
|
||||
};
|
||||
|
||||
static void wbcDomainName_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request the machine's domain name
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param ev tevent context to use for async requests
|
||||
* @param wb_ctx winbind context
|
||||
*
|
||||
* @return tevent_req on success, NULL on failure
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcDomainName_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_domain_name_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_domain_name_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
state->req.cmd = WINBINDD_DOMAIN_NAME;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcDomainName_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcDomainName_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_domain_name_state *state = tevent_req_data(
|
||||
req, struct wbc_domain_name_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->domain_name = talloc_strdup(state, resp->data.domain_name);
|
||||
if (tevent_req_nomem(state->domain_name, subreq)) {
|
||||
return;
|
||||
}
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive the machine's domain name
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param domain_name pointer to a string to hold the domain name
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcDomainName_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
char **domain_name)
|
||||
{
|
||||
struct wbc_domain_name_state *state = tevent_req_data(
|
||||
req, struct wbc_domain_name_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*domain_name = talloc_steal(mem_ctx, state->domain_name);
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
struct wbc_interface_details_state {
|
||||
struct tevent_context *ev;
|
||||
struct wb_context *wb_ctx;
|
||||
struct wbcDomainInfo *dinfo;
|
||||
struct wbcInterfaceDetails *details;
|
||||
};
|
||||
|
||||
static void wbcInterfaceDetails_version(struct tevent_req *subreq);
|
||||
static void wbcInterfaceDetails_info(struct tevent_req *subreq);
|
||||
static void wbcInterfaceDetails_netbios_name(struct tevent_req *subreq);
|
||||
static void wbcInterfaceDetails_domain_name(struct tevent_req *subreq);
|
||||
static void wbcInterfaceDetails_domain_info(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request some useful details about the winbind service
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param ev tevent context to use for async requests
|
||||
* @param wb_ctx winbind context
|
||||
*
|
||||
* @return tevent_req on success, NULL on failure
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcInterfaceDetails_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_interface_details_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct wbc_interface_details_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->ev = ev;
|
||||
state->wb_ctx = wb_ctx;
|
||||
state->details = talloc(state, struct wbcInterfaceDetails);
|
||||
if (tevent_req_nomem(state->details, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
subreq = wbcInterfaceVersion_send(state, ev, wb_ctx);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInterfaceDetails_version, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcInterfaceDetails_version(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_interface_details_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_details_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
|
||||
wbc_status = wbcInterfaceVersion_recv(subreq,
|
||||
&state->details->interface_version);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
subreq = wbcInfo_send(state, state->ev, state->wb_ctx);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInterfaceDetails_info, req);
|
||||
}
|
||||
|
||||
static void wbcInterfaceDetails_info(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_interface_details_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_details_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wbcInfo_recv(subreq, state->details,
|
||||
&state->details->winbind_separator,
|
||||
&state->details->winbind_version);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
subreq = wbcNetbiosName_send(state, state->ev, state->wb_ctx);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInterfaceDetails_netbios_name, req);
|
||||
}
|
||||
|
||||
static void wbcInterfaceDetails_netbios_name(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_interface_details_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_details_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wbcNetbiosName_recv(subreq, state->details,
|
||||
&state->details->netbios_name);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
subreq = wbcDomainName_send(state, state->ev, state->wb_ctx);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInterfaceDetails_domain_name, req);
|
||||
}
|
||||
|
||||
static void wbcInterfaceDetails_domain_name(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_interface_details_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_details_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wbcDomainName_recv(subreq, state->details,
|
||||
&state->details->netbios_domain);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
subreq = wbcDomainInfo_send(state, state->ev, state->wb_ctx,
|
||||
state->details->netbios_domain);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInterfaceDetails_domain_info, req);
|
||||
}
|
||||
|
||||
static void wbcInterfaceDetails_domain_info(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_interface_details_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_details_state);
|
||||
struct wbcDomainInfo *domain;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wbcDomainInfo_recv(subreq, state, &domain);
|
||||
TALLOC_FREE(subreq);
|
||||
if (wbc_status == WBC_ERR_DOMAIN_NOT_FOUND) {
|
||||
tevent_req_done(req);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->details->dns_domain = talloc_strdup(state->details,
|
||||
domain->dns_name);
|
||||
if (tevent_req_nomem(state->details->dns_domain, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TALLOC_FREE(domain);
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive useful information about the winbind service
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param *details pointer to hold the struct wbcInterfaceDetails
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcInterfaceDetails_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct wbcInterfaceDetails **details)
|
||||
{
|
||||
struct wbc_interface_details_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_details_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*details = talloc_steal(mem_ctx, state->details);
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Query useful information about the winbind service
|
||||
@ -795,145 +125,6 @@ done:
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
struct wbc_domain_info_state {
|
||||
struct winbindd_request req;
|
||||
struct wbcDomainInfo *info;
|
||||
};
|
||||
|
||||
static void wbcDomainInfo_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request status of a given trusted domain
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param ev tevent context to use for async requests
|
||||
* @param wb_ctx winbind context
|
||||
* @param domain domain to request status from
|
||||
*
|
||||
* @return tevent_req on success, NULL on failure
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcDomainInfo_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
const char *domain)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_domain_info_state *state;
|
||||
|
||||
if (!domain) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_domain_info_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->info = talloc(state, struct wbcDomainInfo);
|
||||
if (tevent_req_nomem(state->info, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
strncpy(state->req.domain_name, domain,
|
||||
sizeof(state->req.domain_name)-1);
|
||||
|
||||
state->req.cmd = WINBINDD_DOMAIN_INFO;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcDomainInfo_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcDomainInfo_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_domain_info_state *state = tevent_req_data(
|
||||
req, struct wbc_domain_info_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
state->info->short_name = talloc_strdup(state->info,
|
||||
resp->data.domain_info.name);
|
||||
if (tevent_req_nomem(state->info->short_name, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
state->info->dns_name = talloc_strdup(state->info,
|
||||
resp->data.domain_info.alt_name);
|
||||
if (tevent_req_nomem(state->info->dns_name, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
wbc_status = wbcStringToSid(resp->data.domain_info.sid,
|
||||
&state->info->sid);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (resp->data.domain_info.native_mode) {
|
||||
state->info->domain_flags |= WBC_DOMINFO_DOMAIN_NATIVE;
|
||||
}
|
||||
if (resp->data.domain_info.active_directory) {
|
||||
state->info->domain_flags |= WBC_DOMINFO_DOMAIN_AD;
|
||||
}
|
||||
if (resp->data.domain_info.primary) {
|
||||
state->info->domain_flags |= WBC_DOMINFO_DOMAIN_PRIMARY;
|
||||
}
|
||||
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive information about a trusted domain
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param *dinfo pointer to returned struct wbcDomainInfo
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcDomainInfo_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct wbcDomainInfo **dinfo)
|
||||
{
|
||||
struct wbc_domain_info_state *state = tevent_req_data(
|
||||
req, struct wbc_domain_info_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
if (dinfo == NULL) {
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
*dinfo = talloc_steal(mem_ctx, state->info);
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/** @brief Lookup the current status of a trusted domain, sync wrapper
|
||||
*
|
||||
|
835
nsswitch/libwbclient/wbc_util_async.c
Normal file
835
nsswitch/libwbclient/wbc_util_async.c
Normal file
@ -0,0 +1,835 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Winbind client API
|
||||
|
||||
Copyright (C) 2009,2010 Kai Blin <kai@samba.org>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Required Headers */
|
||||
|
||||
#include "replace.h"
|
||||
#include "libwbclient.h"
|
||||
|
||||
struct wbc_ping_state {
|
||||
struct winbindd_request req;
|
||||
};
|
||||
|
||||
static void wbcPing_done(struct tevent_req *subreq);
|
||||
|
||||
/** @brief Ping winbind to see if the service is up and running
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate the request from
|
||||
* @param ev event context to use for async operation
|
||||
* @param wb_ctx winbind context to use
|
||||
*
|
||||
* @return Async request on successful dispatch of the request, NULL on error
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcPing_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_ping_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_ping_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
state->req.cmd = WINBINDD_PING;
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcPing_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcPing_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_ping_state *state = tevent_req_data(
|
||||
req, struct wbc_ping_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/** @brief Receive ping response from winbind
|
||||
*
|
||||
* @param req async request sent in #wbcPing_send
|
||||
*
|
||||
* @return NT_STATUS_OK on success, an error status on error.
|
||||
*/
|
||||
|
||||
wbcErr wbcPing_recv(struct tevent_req *req)
|
||||
{
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
struct wbc_interface_version_state {
|
||||
struct winbindd_request req;
|
||||
uint32_t version;
|
||||
};
|
||||
|
||||
static void wbcInterfaceVersion_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request the interface version from winbind
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param ev tevent context to use for async requests
|
||||
* @param wb_ctx winbind context
|
||||
*
|
||||
* @return tevevt_req on success, NULL on failure
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcInterfaceVersion_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_interface_version_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_interface_version_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
state->req.cmd = WINBINDD_INTERFACE_VERSION;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInterfaceVersion_done, req);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcInterfaceVersion_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_interface_version_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_version_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->version = resp->data.interface_version;
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive the winbind interface version
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param interface_version pointer to uint32_t to hold the interface
|
||||
* version
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcInterfaceVersion_recv(struct tevent_req *req,
|
||||
uint32_t *interface_version)
|
||||
{
|
||||
struct wbc_interface_version_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_version_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*interface_version = state->version;
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
struct wbc_info_state {
|
||||
struct winbindd_request req;
|
||||
char separator;
|
||||
char *version_string;
|
||||
};
|
||||
|
||||
static void wbcInfo_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request information about the winbind service
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param ev tevent context to use for async requests
|
||||
* @param wb_ctx winbind context
|
||||
*
|
||||
* @return tevent_req on success, NULL on failure
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcInfo_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_info_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_info_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
state->req.cmd = WINBINDD_INFO;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInfo_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcInfo_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_info_state *state = tevent_req_data(
|
||||
req, struct wbc_info_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->version_string = talloc_strdup(state,
|
||||
resp->data.info.samba_version);
|
||||
if (tevent_req_nomem(state->version_string, subreq)) {
|
||||
return;
|
||||
}
|
||||
state->separator = resp->data.info.winbind_separator;
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive information about the running winbind service
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param winbind_separator pointer to a char to hold the separator
|
||||
* @param version_string pointer to a string to hold the version string
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcInfo_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
char *winbind_separator,
|
||||
char **version_string)
|
||||
{
|
||||
struct wbc_info_state *state = tevent_req_data(
|
||||
req, struct wbc_info_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*winbind_separator = state->separator;
|
||||
*version_string = talloc_steal(mem_ctx, state->version_string);
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
struct wbc_netbios_name_state {
|
||||
struct winbindd_request req;
|
||||
char *netbios_name;
|
||||
};
|
||||
|
||||
static void wbcNetbiosName_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request the machine's netbios name
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param ev tevent context to use for async requests
|
||||
* @param wb_ctx winbind context
|
||||
*
|
||||
* @return tevent_req on success, NULL on failure
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcNetbiosName_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_netbios_name_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_netbios_name_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
state->req.cmd = WINBINDD_NETBIOS_NAME;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcNetbiosName_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcNetbiosName_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_netbios_name_state *state = tevent_req_data(
|
||||
req, struct wbc_netbios_name_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->netbios_name = talloc_strdup(state,
|
||||
resp->data.info.samba_version);
|
||||
if (tevent_req_nomem(state->netbios_name, subreq)) {
|
||||
return;
|
||||
}
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive the machine's netbios name
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param netbios_name pointer to a string to hold the netbios name
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcNetbiosName_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
char **netbios_name)
|
||||
{
|
||||
struct wbc_netbios_name_state *state = tevent_req_data(
|
||||
req, struct wbc_netbios_name_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*netbios_name = talloc_steal(mem_ctx, state->netbios_name);
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
struct wbc_domain_name_state {
|
||||
struct winbindd_request req;
|
||||
char *domain_name;
|
||||
};
|
||||
|
||||
static void wbcDomainName_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request the machine's domain name
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param ev tevent context to use for async requests
|
||||
* @param wb_ctx winbind context
|
||||
*
|
||||
* @return tevent_req on success, NULL on failure
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcDomainName_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_domain_name_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_domain_name_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
state->req.cmd = WINBINDD_DOMAIN_NAME;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcDomainName_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcDomainName_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_domain_name_state *state = tevent_req_data(
|
||||
req, struct wbc_domain_name_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->domain_name = talloc_strdup(state, resp->data.domain_name);
|
||||
if (tevent_req_nomem(state->domain_name, subreq)) {
|
||||
return;
|
||||
}
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive the machine's domain name
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param domain_name pointer to a string to hold the domain name
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcDomainName_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
char **domain_name)
|
||||
{
|
||||
struct wbc_domain_name_state *state = tevent_req_data(
|
||||
req, struct wbc_domain_name_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*domain_name = talloc_steal(mem_ctx, state->domain_name);
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
struct wbc_interface_details_state {
|
||||
struct tevent_context *ev;
|
||||
struct wb_context *wb_ctx;
|
||||
struct wbcDomainInfo *dinfo;
|
||||
struct wbcInterfaceDetails *details;
|
||||
};
|
||||
|
||||
static void wbcInterfaceDetails_version(struct tevent_req *subreq);
|
||||
static void wbcInterfaceDetails_info(struct tevent_req *subreq);
|
||||
static void wbcInterfaceDetails_netbios_name(struct tevent_req *subreq);
|
||||
static void wbcInterfaceDetails_domain_name(struct tevent_req *subreq);
|
||||
static void wbcInterfaceDetails_domain_info(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request some useful details about the winbind service
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param ev tevent context to use for async requests
|
||||
* @param wb_ctx winbind context
|
||||
*
|
||||
* @return tevent_req on success, NULL on failure
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcInterfaceDetails_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_interface_details_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct wbc_interface_details_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->ev = ev;
|
||||
state->wb_ctx = wb_ctx;
|
||||
state->details = talloc(state, struct wbcInterfaceDetails);
|
||||
if (tevent_req_nomem(state->details, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
subreq = wbcInterfaceVersion_send(state, ev, wb_ctx);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInterfaceDetails_version, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcInterfaceDetails_version(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_interface_details_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_details_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
|
||||
wbc_status = wbcInterfaceVersion_recv(subreq,
|
||||
&state->details->interface_version);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
subreq = wbcInfo_send(state, state->ev, state->wb_ctx);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInterfaceDetails_info, req);
|
||||
}
|
||||
|
||||
static void wbcInterfaceDetails_info(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_interface_details_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_details_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wbcInfo_recv(subreq, state->details,
|
||||
&state->details->winbind_separator,
|
||||
&state->details->winbind_version);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
subreq = wbcNetbiosName_send(state, state->ev, state->wb_ctx);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInterfaceDetails_netbios_name, req);
|
||||
}
|
||||
|
||||
static void wbcInterfaceDetails_netbios_name(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_interface_details_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_details_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wbcNetbiosName_recv(subreq, state->details,
|
||||
&state->details->netbios_name);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
subreq = wbcDomainName_send(state, state->ev, state->wb_ctx);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInterfaceDetails_domain_name, req);
|
||||
}
|
||||
|
||||
static void wbcInterfaceDetails_domain_name(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_interface_details_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_details_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wbcDomainName_recv(subreq, state->details,
|
||||
&state->details->netbios_domain);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
subreq = wbcDomainInfo_send(state, state->ev, state->wb_ctx,
|
||||
state->details->netbios_domain);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcInterfaceDetails_domain_info, req);
|
||||
}
|
||||
|
||||
static void wbcInterfaceDetails_domain_info(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_interface_details_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_details_state);
|
||||
struct wbcDomainInfo *domain;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wbcDomainInfo_recv(subreq, state, &domain);
|
||||
TALLOC_FREE(subreq);
|
||||
if (wbc_status == WBC_ERR_DOMAIN_NOT_FOUND) {
|
||||
tevent_req_done(req);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
state->details->dns_domain = talloc_strdup(state->details,
|
||||
domain->dns_name);
|
||||
if (tevent_req_nomem(state->details->dns_domain, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TALLOC_FREE(domain);
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive useful information about the winbind service
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param *details pointer to hold the struct wbcInterfaceDetails
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcInterfaceDetails_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct wbcInterfaceDetails **details)
|
||||
{
|
||||
struct wbc_interface_details_state *state = tevent_req_data(
|
||||
req, struct wbc_interface_details_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
*details = talloc_steal(mem_ctx, state->details);
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
struct wbc_domain_info_state {
|
||||
struct winbindd_request req;
|
||||
struct wbcDomainInfo *info;
|
||||
};
|
||||
|
||||
static void wbcDomainInfo_done(struct tevent_req *subreq);
|
||||
|
||||
/**
|
||||
* @brief Request status of a given trusted domain
|
||||
*
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param ev tevent context to use for async requests
|
||||
* @param wb_ctx winbind context
|
||||
* @param domain domain to request status from
|
||||
*
|
||||
* @return tevent_req on success, NULL on failure
|
||||
*/
|
||||
|
||||
struct tevent_req *wbcDomainInfo_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct wb_context *wb_ctx,
|
||||
const char *domain)
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct wbc_domain_info_state *state;
|
||||
|
||||
if (!domain) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct wbc_domain_info_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->info = talloc(state, struct wbcDomainInfo);
|
||||
if (tevent_req_nomem(state->info, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->req);
|
||||
|
||||
strncpy(state->req.domain_name, domain,
|
||||
sizeof(state->req.domain_name)-1);
|
||||
|
||||
state->req.cmd = WINBINDD_DOMAIN_INFO;
|
||||
|
||||
subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, wbcDomainInfo_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void wbcDomainInfo_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wbc_domain_info_state *state = tevent_req_data(
|
||||
req, struct wbc_domain_info_state);
|
||||
struct winbindd_response *resp;
|
||||
wbcErr wbc_status;
|
||||
|
||||
wbc_status = wb_trans_recv(subreq, state, &resp);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
state->info->short_name = talloc_strdup(state->info,
|
||||
resp->data.domain_info.name);
|
||||
if (tevent_req_nomem(state->info->short_name, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
state->info->dns_name = talloc_strdup(state->info,
|
||||
resp->data.domain_info.alt_name);
|
||||
if (tevent_req_nomem(state->info->dns_name, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
wbc_status = wbcStringToSid(resp->data.domain_info.sid,
|
||||
&state->info->sid);
|
||||
if (!WBC_ERROR_IS_OK(wbc_status)) {
|
||||
tevent_req_error(req, wbc_status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (resp->data.domain_info.native_mode) {
|
||||
state->info->domain_flags |= WBC_DOMINFO_DOMAIN_NATIVE;
|
||||
}
|
||||
if (resp->data.domain_info.active_directory) {
|
||||
state->info->domain_flags |= WBC_DOMINFO_DOMAIN_AD;
|
||||
}
|
||||
if (resp->data.domain_info.primary) {
|
||||
state->info->domain_flags |= WBC_DOMINFO_DOMAIN_PRIMARY;
|
||||
}
|
||||
|
||||
TALLOC_FREE(resp);
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive information about a trusted domain
|
||||
*
|
||||
* @param req tevent_req containing the request
|
||||
* @param mem_ctx talloc context to allocate memory from
|
||||
* @param *dinfo pointer to returned struct wbcDomainInfo
|
||||
*
|
||||
* @return #wbcErr
|
||||
*/
|
||||
|
||||
wbcErr wbcDomainInfo_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct wbcDomainInfo **dinfo)
|
||||
{
|
||||
struct wbc_domain_info_state *state = tevent_req_data(
|
||||
req, struct wbc_domain_info_state);
|
||||
wbcErr wbc_status;
|
||||
|
||||
if (tevent_req_is_wbcerr(req, &wbc_status)) {
|
||||
tevent_req_received(req);
|
||||
return wbc_status;
|
||||
}
|
||||
|
||||
if (dinfo == NULL) {
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
*dinfo = talloc_steal(mem_ctx, state->info);
|
||||
|
||||
tevent_req_received(req);
|
||||
return WBC_ERR_SUCCESS;
|
||||
}
|
@ -2006,11 +2006,17 @@ LIBWBCLIENT_OBJ0 = ../nsswitch/libwbclient/wbclient.o \
|
||||
../nsswitch/libwbclient/wbc_idmap.o \
|
||||
../nsswitch/libwbclient/wbc_sid.o \
|
||||
../nsswitch/libwbclient/wbc_guid.o \
|
||||
../nsswitch/libwbclient/wbc_pam.o \
|
||||
../nsswitch/libwbclient/wb_reqtrans.o \
|
||||
../nsswitch/libwbclient/wbc_async.o
|
||||
../nsswitch/libwbclient/wbc_pam.o
|
||||
|
||||
LIBWBCLIENT_OBJ_ASYNC = ../nsswitch/libwbclient/wb_reqtrans.o \
|
||||
../nsswitch/libwbclient/wbc_async.o \
|
||||
../nsswitch/libwbclient/wbc_util_async.o\
|
||||
../nsswitch/libwbclient/wbc_idmap_async.o \
|
||||
../nsswitch/libwbclient/wbc_sid_async.o \
|
||||
../nsswitch/libwbclient/wbc_pam_async.o
|
||||
|
||||
LIBWBCLIENT_OBJ = $(LIBWBCLIENT_OBJ0) \
|
||||
$(LIBWBCLIENT_OBJ_ASYNC) \
|
||||
$(WBCOMMON_OBJ) \
|
||||
$(LIBREPLACE_OBJ) \
|
||||
../lib/async_req/async_sock.o \
|
||||
@ -2038,9 +2044,9 @@ $(LIBWBCLIENT_SHARED_TARGET): $(LIBWBCLIENT_SHARED_TARGET_SONAME)
|
||||
@rm -f $@
|
||||
@ln -f -s `basename $(LIBWBCLIENT_SHARED_TARGET_SONAME)` $@
|
||||
|
||||
$(LIBWBCLIENT_STATIC_TARGET): $(BINARY_PREREQS) $(LIBWBCLIENT_OBJ0) $(WBCOMMON_OBJ)
|
||||
$(LIBWBCLIENT_STATIC_TARGET): $(BINARY_PREREQS) $(LIBWBCLIENT_OBJ0) $(LIBWBCLIENT_OBJ_ASYNC) $(WBCOMMON_OBJ)
|
||||
@echo Linking non-shared library $@
|
||||
@-$(AR) -rc $@ $(LIBWBCLIENT_OBJ0) $(WBCOMMON_OBJ)
|
||||
@-$(AR) -rc $@ $(LIBWBCLIENT_OBJ0) $(LIBWBCLIENT_OBJ_ASYNC) $(WBCOMMON_OBJ)
|
||||
|
||||
libwbclient: $(LIBWBCLIENT)
|
||||
|
||||
|
@ -6,7 +6,7 @@ SUBSYSTEM = smbtorture
|
||||
OUTPUT_TYPE = MERGED_OBJ
|
||||
INIT_FUNCTION = torture_winbind_init
|
||||
PRIVATE_DEPENDENCIES = \
|
||||
LIBWBCLIENT LIBWINBIND-CLIENT torture PAM_ERRORS
|
||||
LIBWBCLIENT LIBWBCLIENT_ASYNC LIBWINBIND-CLIENT torture PAM_ERRORS
|
||||
# End SUBSYSTEM TORTURE_WINBIND
|
||||
#################################
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user