1
0
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:
Kai Blin 2010-10-12 06:13:57 +02:00
parent f768b32e37
commit 5ad0ed2181
9 changed files with 2 additions and 2186 deletions

View File

@ -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 )

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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',
)

View File

@ -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
#################################

View File

@ -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
)