mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
libwbclient: Remove half-finished async implementation
The old approach on doing async libwbclient was never really finished. Go ahead and remove this implementation. Autobuild-User: Kai Blin <kai@samba.org> Autobuild-Date: Tue Oct 12 07:05:31 UTC 2010 on sn-devel-104
This commit is contained in:
parent
f768b32e37
commit
5ad0ed2181
@ -8,17 +8,3 @@ LIBWBCLIENT_OBJ_FILES = $(addprefix $(libwbclientsrcdir)/, wbc_guid.o \
|
||||
wbc_pwd.o \
|
||||
wbc_sid.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 )
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "lib/util/data_blob.h"
|
||||
#include "lib/util/time.h"
|
||||
#include "nsswitch/libwbclient/wbclient.h"
|
||||
#include "nsswitch/libwbclient/wbc_async.h"
|
||||
#include "torture/smbtorture.h"
|
||||
#include "torture/winbind/proto.h"
|
||||
#include "lib/util/util_net.h"
|
||||
@ -46,17 +45,6 @@
|
||||
#define torture_assert_wbc_ok(torture_ctx,expr,cmt) \
|
||||
torture_assert_wbc_equal(torture_ctx,expr,WBC_ERR_SUCCESS,cmt)
|
||||
|
||||
|
||||
static void wbc_debug_torture(void *private_data, enum wbcDebugLevel level,
|
||||
const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
|
||||
static void wbc_debug_torture(void *private_data, enum wbcDebugLevel level,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
struct torture_context *tctx = talloc_get_type_abort(private_data,
|
||||
struct torture_context);
|
||||
torture_comment(tctx, "%s", talloc_vasprintf(tctx, fmt, ap));
|
||||
}
|
||||
|
||||
static bool test_wbc_ping(struct torture_context *tctx)
|
||||
{
|
||||
torture_assert_wbc_ok(tctx, wbcPing(),
|
||||
@ -65,24 +53,6 @@ static bool test_wbc_ping(struct torture_context *tctx)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_wbc_ping_async(struct torture_context *tctx)
|
||||
{
|
||||
struct wb_context *wb_ctx;
|
||||
struct tevent_req *req;
|
||||
|
||||
wb_ctx = wb_context_init(tctx, NULL);
|
||||
|
||||
req = wbcPing_send(tctx, tctx->ev, wb_ctx);
|
||||
torture_assert(tctx, req, "wbcPing_send failed");
|
||||
|
||||
if(!tevent_req_poll(req, tctx->ev)) {
|
||||
return false;
|
||||
}
|
||||
torture_assert_wbc_ok(tctx, wbcPing_recv(req), "wbcPing_recv failed");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool test_wbc_pingdc(struct torture_context *tctx)
|
||||
{
|
||||
torture_assert_wbc_equal(tctx, wbcPingDc("random_string", NULL), WBC_ERR_NOT_IMPLEMENTED,
|
||||
@ -253,77 +223,6 @@ static bool test_wbc_users(struct torture_context *tctx)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_wbc_users_async(struct torture_context *tctx)
|
||||
{
|
||||
struct wb_context *wb_ctx;
|
||||
struct tevent_req *req;
|
||||
const char *domain_name = NULL;
|
||||
uint32_t num_users;
|
||||
const char **users;
|
||||
int i;
|
||||
struct wbcInterfaceDetails *details;
|
||||
|
||||
wb_ctx = wb_context_init(tctx, NULL);
|
||||
wbcSetDebug(wb_ctx, wbc_debug_torture, tctx);
|
||||
|
||||
req = wbcInterfaceDetails_send(tctx, tctx->ev, wb_ctx);
|
||||
torture_assert(tctx, req, "wbcInterfaceDetails_send failed");
|
||||
|
||||
if(!tevent_req_poll(req, tctx->ev)) {
|
||||
return false;
|
||||
}
|
||||
torture_assert_wbc_ok(tctx,
|
||||
wbcInterfaceDetails_recv(req, tctx, &details),
|
||||
"wbcInterfaceDetails_recv failed");
|
||||
|
||||
domain_name = talloc_strdup(tctx, details->netbios_domain);
|
||||
wbcFreeMemory(details);
|
||||
|
||||
/* No async implementation of this yet. */
|
||||
torture_assert_wbc_ok(tctx, wbcListUsers(domain_name, &num_users, &users),
|
||||
"wbcListUsers failed");
|
||||
torture_assert(tctx, !(num_users > 0 && !users),
|
||||
"wbcListUsers returned invalid results");
|
||||
|
||||
for (i=0; i < MIN(num_users,100); i++) {
|
||||
|
||||
struct wbcDomainSid sid, *sids;
|
||||
enum wbcSidType name_type;
|
||||
char *domain;
|
||||
char *name;
|
||||
uint32_t num_sids;
|
||||
|
||||
req = wbcLookupName_send(tctx, tctx->ev, wb_ctx, domain_name,
|
||||
users[i]);
|
||||
torture_assert(tctx, req, "wbcLookupName_send failed");
|
||||
|
||||
if(!tevent_req_poll(req, tctx->ev)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
torture_assert_wbc_ok(tctx,
|
||||
wbcLookupName_recv(req, &sid, &name_type),
|
||||
"wbcLookupName_recv failed");
|
||||
|
||||
torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_USER,
|
||||
"wbcLookupName expected WBC_SID_NAME_USER");
|
||||
torture_assert_wbc_ok(tctx, wbcLookupSid(&sid, &domain, &name, &name_type),
|
||||
"wbcLookupSid failed");
|
||||
torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_USER,
|
||||
"wbcLookupSid expected WBC_SID_NAME_USER");
|
||||
torture_assert(tctx, name,
|
||||
"wbcLookupSid returned no name");
|
||||
wbcFreeMemory(domain);
|
||||
wbcFreeMemory(name);
|
||||
torture_assert_wbc_ok(tctx, wbcLookupUserSids(&sid, true, &num_sids, &sids),
|
||||
"wbcLookupUserSids failed");
|
||||
wbcFreeMemory(sids);
|
||||
}
|
||||
wbcFreeMemory(users);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_wbc_groups(struct torture_context *tctx)
|
||||
{
|
||||
const char *domain_name = NULL;
|
||||
@ -782,7 +681,6 @@ struct torture_suite *torture_wbclient(void)
|
||||
struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "WBCLIENT");
|
||||
|
||||
torture_suite_add_simple_test(suite, "wbcPing", test_wbc_ping);
|
||||
torture_suite_add_simple_test(suite, "wbcPing_async", test_wbc_ping_async);
|
||||
torture_suite_add_simple_test(suite, "wbcPingDc", test_wbc_pingdc);
|
||||
torture_suite_add_simple_test(suite, "wbcLibraryDetails", test_wbc_library_details);
|
||||
torture_suite_add_simple_test(suite, "wbcInterfaceDetails", test_wbc_interface_details);
|
||||
@ -791,7 +689,6 @@ struct torture_suite *torture_wbclient(void)
|
||||
torture_suite_add_simple_test(suite, "wbcGuidToString", test_wbc_guidtostring);
|
||||
torture_suite_add_simple_test(suite, "wbcDomainInfo", test_wbc_domain_info);
|
||||
torture_suite_add_simple_test(suite, "wbcListUsers", test_wbc_users);
|
||||
torture_suite_add_simple_test(suite, "wbcListUsers_async", test_wbc_users_async);
|
||||
torture_suite_add_simple_test(suite, "wbcListGroups", test_wbc_groups);
|
||||
torture_suite_add_simple_test(suite, "wbcListTrusts", test_wbc_trusts);
|
||||
torture_suite_add_simple_test(suite, "wbcLookupDomainController", test_wbc_lookupdc);
|
||||
|
@ -1,448 +0,0 @@
|
||||
/*
|
||||
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 "wbc_async.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;
|
||||
}
|
@ -1,484 +0,0 @@
|
||||
/*
|
||||
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"
|
||||
#include "wbc_async.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;
|
||||
}
|
@ -1,291 +0,0 @@
|
||||
/*
|
||||
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"
|
||||
#include "wbc_async.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 domain 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 of a domain and name to a domain SID.
|
||||
*
|
||||
* @param req The tevent request calling this function.
|
||||
*
|
||||
* @param sid A pointer to store the sid looked up.
|
||||
*
|
||||
* @param name_type Pointer to store the resolved SID name 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 req The tevent request calling this function.
|
||||
*
|
||||
* @param mem_ctx A talloc context to move results to.
|
||||
*
|
||||
* @param pdomain A pointer to store the resolved domain name
|
||||
* (possibly "").
|
||||
*
|
||||
* @param pname A pointer to store the resolved user or group name.
|
||||
*
|
||||
* @param pname_type A pointer to store 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,836 +0,0 @@
|
||||
/*
|
||||
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 "wbc_async.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;
|
||||
}
|
@ -4,11 +4,3 @@ bld.SAMBA_SUBSYSTEM('LIBWBCLIENT',
|
||||
source='wbc_guid.c wbc_idmap.c wbclient.c wbc_pam.c wbc_pwd.c wbc_sid.c wbc_util.c',
|
||||
deps='LIBWINBIND-CLIENT'
|
||||
)
|
||||
|
||||
|
||||
bld.SAMBA_SUBSYSTEM('LIBWBCLIENT_ASYNC',
|
||||
source='wbc_async.c wbc_idmap_async.c wbc_pam_async.c wbc_sid_async.c wbc_util_async.c wb_reqtrans.c',
|
||||
cflags='-DWINBINDD_SOCKET_DIR=\"%s\"' % bld.env.WINBINDD_SOCKET_DIR,
|
||||
public_deps='LIBASYNC_REQ tevent talloc UTIL_TEVENT LIBWBCLIENT',
|
||||
)
|
||||
|
||||
|
@ -6,7 +6,7 @@ SUBSYSTEM = smbtorture
|
||||
OUTPUT_TYPE = MERGED_OBJ
|
||||
INIT_FUNCTION = torture_winbind_init
|
||||
PRIVATE_DEPENDENCIES = \
|
||||
LIBWBCLIENT LIBWBCLIENT_ASYNC LIBWINBIND-CLIENT torture PAM_ERRORS
|
||||
LIBWBCLIENT LIBWINBIND-CLIENT torture PAM_ERRORS
|
||||
# End SUBSYSTEM TORTURE_WINBIND
|
||||
#################################
|
||||
|
||||
|
@ -5,6 +5,6 @@ bld.SAMBA_MODULE('TORTURE_WINBIND',
|
||||
autoproto='proto.h',
|
||||
subsystem='smbtorture',
|
||||
init_function='torture_winbind_init',
|
||||
deps='LIBWBCLIENT LIBWBCLIENT_ASYNC LIBWINBIND-CLIENT torture PAM_ERRORS',
|
||||
deps='LIBWBCLIENT LIBWINBIND-CLIENT torture PAM_ERRORS',
|
||||
internal_module=True
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user