}
struct np_proxy_state {
- struct async_req_queue *read_queue;
- struct async_req_queue *write_queue;
+ struct tevent_queue *read_queue;
+ struct tevent_queue *write_queue;
int fd;
uint8_t *msg;
result->msg = NULL;
- result->read_queue = async_req_queue_init(result);
+ result->read_queue = tevent_queue_create(result, "np_read");
if (result->read_queue == NULL) {
goto fail;
}
- result->write_queue = async_req_queue_init(result);
+ result->write_queue = tevent_queue_create(result, "np_write");
if (result->write_queue == NULL) {
goto fail;
}
ssize_t nwritten;
};
-static void np_write_trigger(struct async_req *req);
static void np_write_done(struct tevent_req *subreq);
-struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
- struct fake_file_handle *handle,
- const uint8_t *data, size_t len)
+struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+ struct fake_file_handle *handle,
+ const uint8_t *data, size_t len)
{
- struct async_req *result;
+ struct tevent_req *req;
struct np_write_state *state;
NTSTATUS status;
DEBUG(6, ("np_write_send: len: %d\n", (int)len));
dump_data(50, data, len);
- if (!async_req_setup(mem_ctx, &result, &state,
- struct np_write_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct np_write_state);
+ if (req == NULL) {
return NULL;
}
if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
struct np_proxy_state *p = talloc_get_type_abort(
handle->private_data, struct np_proxy_state);
+ struct tevent_req *subreq;
state->ev = ev;
state->p = p;
state->iov.iov_base = CONST_DISCARD(void *, data);
state->iov.iov_len = len;
- if (!async_req_enqueue(p->write_queue, ev, result,
- np_write_trigger)) {
+ subreq = writev_send(state, ev, p->write_queue, p->fd,
+ false, &state->iov, 1);
+ if (subreq == NULL) {
goto fail;
}
- return result;
+ tevent_req_set_callback(subreq, np_write_done, req);
+ return req;
}
status = NT_STATUS_INVALID_HANDLE;
post_status:
- if (async_post_ntstatus(result, ev, status)) {
- return result;
+ if (NT_STATUS_IS_OK(status)) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_nterror(req, status);
}
+ return tevent_req_post(req, ev);
fail:
- TALLOC_FREE(result);
+ TALLOC_FREE(req);
return NULL;
}
-static void np_write_trigger(struct async_req *req)
-{
- struct np_write_state *state = talloc_get_type_abort(
- req->private_data, struct np_write_state);
- struct tevent_req *subreq;
-
- subreq = writev_send(state, state->ev, NULL, state->p->fd,
- &state->iov, 1);
- if (async_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, np_write_done, req);
-}
-
static void np_write_done(struct tevent_req *subreq)
{
- struct async_req *req =
- tevent_req_callback_data(subreq, struct async_req);
- struct np_write_state *state = talloc_get_type_abort(
- req->private_data, struct np_write_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct np_write_state *state = tevent_req_data(
+ req, struct np_write_state);
ssize_t received;
int err;
received = writev_recv(subreq, &err);
if (received < 0) {
- async_req_nterror(req, map_nt_error_from_unix(err));
+ tevent_req_nterror(req, map_nt_error_from_unix(err));
return;
}
state->nwritten = received;
- async_req_done(req);
+ tevent_req_done(req);
}
-NTSTATUS np_write_recv(struct async_req *req, ssize_t *pnwritten)
+NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten)
{
- struct np_write_state *state = talloc_get_type_abort(
- req->private_data, struct np_write_state);
+ struct np_write_state *state = tevent_req_data(
+ req, struct np_write_state);
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status)) {
return status;
}
*pnwritten = state->nwritten;
bool is_data_outstanding;
};
-static void np_read_trigger(struct async_req *req);
+static void np_read_trigger(struct tevent_req *req, void *private_data);
static void np_read_done(struct tevent_req *subreq);
-struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
- struct fake_file_handle *handle,
- uint8_t *data, size_t len)
+struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+ struct fake_file_handle *handle,
+ uint8_t *data, size_t len)
{
- struct async_req *result;
+ struct tevent_req *req;
struct np_read_state *state;
NTSTATUS status;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct np_read_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct np_read_state);
+ if (req == NULL) {
return NULL;
}
state->data = data;
state->len = len;
- if (!async_req_enqueue(p->read_queue, ev, result,
- np_read_trigger)) {
+ if (!tevent_queue_add(p->read_queue, ev, req, np_read_trigger,
+ NULL)) {
goto fail;
}
- return result;
+ return req;
}
status = NT_STATUS_INVALID_HANDLE;
post_status:
- if (async_post_ntstatus(result, ev, status)) {
- return result;
+ if (NT_STATUS_IS_OK(status)) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_nterror(req, status);
}
+ return tevent_req_post(req, ev);
fail:
- TALLOC_FREE(result);
+ TALLOC_FREE(req);
return NULL;
}
-static void np_read_trigger(struct async_req *req)
+static void np_read_trigger(struct tevent_req *req, void *private_data)
{
- struct np_read_state *state = talloc_get_type_abort(
- req->private_data, struct np_read_state);
+ struct np_read_state *state = tevent_req_data(
+ req, struct np_read_state);
struct tevent_req *subreq;
subreq = read_packet_send(state, state->ev, state->p->fd,
RPC_HEADER_LEN, rpc_frag_more_fn, NULL);
- if (async_req_nomem(subreq, req)) {
+ if (tevent_req_nomem(subreq, req)) {
return;
}
tevent_req_set_callback(subreq, np_read_done, req);
static void np_read_done(struct tevent_req *subreq)
{
- struct async_req *req =
- tevent_req_callback_data(subreq, struct async_req);
- struct np_read_state *state = talloc_get_type_abort(
- req->private_data, struct np_read_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct np_read_state *state = tevent_req_data(
+ req, struct np_read_state);
ssize_t received;
size_t thistime;
int err;
received = read_packet_recv(subreq, state->p, &state->p->msg, &err);
TALLOC_FREE(subreq);
if (received == -1) {
- async_req_nterror(req, map_nt_error_from_unix(err));
+ tevent_req_nterror(req, map_nt_error_from_unix(err));
return;
}
state->is_data_outstanding = false;
}
- async_req_done(req);
+ tevent_req_done(req);
return;
}
-NTSTATUS np_read_recv(struct async_req *req, ssize_t *nread,
+NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
bool *is_data_outstanding)
{
- struct np_read_state *state = talloc_get_type_abort(
- req->private_data, struct np_read_state);
+ struct np_read_state *state = tevent_req_data(
+ req, struct np_read_state);
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status)) {
return status;
}
*nread = state->nread;
*presult = result;
return NT_STATUS_OK;
}
+
+/*******************************************************************
+ gets a domain user's groups from their already-calculated NT_USER_TOKEN
+ ********************************************************************/
+
+static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
+ size_t num_sids,
+ const DOM_SID *sids,
+ int *numgroups,
+ struct samr_RidWithAttribute **pgids)
+{
+ int i;
+
+ *numgroups=0;
+ *pgids = NULL;
+
+ for (i=0; i<num_sids; i++) {
+ struct samr_RidWithAttribute gid;
+ if (!sid_peek_check_rid(domain_sid, &sids[i], &gid.rid)) {
+ continue;
+ }
+ gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
+ SE_GROUP_ENABLED);
+ ADD_TO_ARRAY(mem_ctx, struct samr_RidWithAttribute,
+ gid, pgids, numgroups);
+ if (*pgids == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ inits a netr_SamBaseInfo structure from an auth_serversupplied_info.
+*****************************************************************************/
+
+static NTSTATUS serverinfo_to_SamInfo_base(TALLOC_CTX *mem_ctx,
+ struct auth_serversupplied_info *server_info,
+ uint8_t *pipe_session_key,
+ size_t pipe_session_key_len,
+ struct netr_SamBaseInfo *base)
+{
+ struct samu *sampw;
+ struct samr_RidWithAttribute *gids = NULL;
+ const DOM_SID *user_sid = NULL;
+ const DOM_SID *group_sid = NULL;
+ DOM_SID domain_sid;
+ uint32 user_rid, group_rid;
+ NTSTATUS status;
+
+ int num_gids = 0;
+ const char *my_name;
+
+ struct netr_UserSessionKey user_session_key;
+ struct netr_LMSessionKey lm_session_key;
+
+ NTTIME last_logon, last_logoff, acct_expiry, last_password_change;
+ NTTIME allow_password_change, force_password_change;
+ struct samr_RidWithAttributeArray groups;
+ int i;
+ struct dom_sid2 *sid = NULL;
+
+ ZERO_STRUCT(user_session_key);
+ ZERO_STRUCT(lm_session_key);
+
+ sampw = server_info->sam_account;
+
+ user_sid = pdb_get_user_sid(sampw);
+ group_sid = pdb_get_group_sid(sampw);
+
+ if (pipe_session_key && pipe_session_key_len != 16) {
+ DEBUG(0,("serverinfo_to_SamInfo3: invalid "
+ "pipe_session_key_len[%zu] != 16\n",
+ pipe_session_key_len));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ if ((user_sid == NULL) || (group_sid == NULL)) {
+ DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ sid_copy(&domain_sid, user_sid);
+ sid_split_rid(&domain_sid, &user_rid);
+
+ sid = sid_dup_talloc(mem_ctx, &domain_sid);
+ if (!sid) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) {
+ DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid "
+ "%s\n but group sid %s.\n"
+ "The conflicting domain portions are not "
+ "supported for NETLOGON calls\n",
+ pdb_get_domain(sampw),
+ pdb_get_username(sampw),
+ sid_string_dbg(user_sid),
+ sid_string_dbg(group_sid)));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if(server_info->login_server) {
+ my_name = server_info->login_server;
+ } else {
+ my_name = global_myname();
+ }
+
+ status = nt_token_to_group_list(mem_ctx, &domain_sid,
+ server_info->num_sids,
+ server_info->sids,
+ &num_gids, &gids);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (server_info->user_session_key.length) {
+ memcpy(user_session_key.key,
+ server_info->user_session_key.data,
+ MIN(sizeof(user_session_key.key),
+ server_info->user_session_key.length));
+ if (pipe_session_key) {
+ arcfour_crypt(user_session_key.key, pipe_session_key, 16);
+ }
+ }
+ if (server_info->lm_session_key.length) {
+ memcpy(lm_session_key.key,
+ server_info->lm_session_key.data,
+ MIN(sizeof(lm_session_key.key),
+ server_info->lm_session_key.length));
+ if (pipe_session_key) {
+ arcfour_crypt(lm_session_key.key, pipe_session_key, 8);
+ }
+ }
+
+ groups.count = num_gids;
+ groups.rids = TALLOC_ARRAY(mem_ctx, struct samr_RidWithAttribute, groups.count);
+ if (!groups.rids) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i < groups.count; i++) {
+ groups.rids[i].rid = gids[i].rid;
+ groups.rids[i].attributes = gids[i].attributes;
+ }
+
+ unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw));
+ unix_to_nt_time(&last_logoff, get_time_t_max());
+ unix_to_nt_time(&acct_expiry, get_time_t_max());
+ unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(sampw));
+ unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(sampw));
+ unix_to_nt_time(&force_password_change, pdb_get_pass_must_change_time(sampw));
+
+ base->last_logon = last_logon;
+ base->last_logoff = last_logoff;
+ base->acct_expiry = acct_expiry;
+ base->last_password_change = last_password_change;
+ base->allow_password_change = allow_password_change;
+ base->force_password_change = force_password_change;
+ base->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(sampw));
+ base->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(sampw));
+ base->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(sampw));
+ base->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(sampw));
+ base->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(sampw));
+ base->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(sampw));
+ base->logon_count = 0; /* ?? */
+ base->bad_password_count = 0; /* ?? */
+ base->rid = user_rid;
+ base->primary_gid = group_rid;
+ base->groups = groups;
+ base->user_flags = NETLOGON_EXTRA_SIDS;
+ base->key = user_session_key;
+ base->logon_server.string = my_name;
+ base->domain.string = talloc_strdup(mem_ctx, pdb_get_domain(sampw));
+ base->domain_sid = sid;
+ base->LMSessKey = lm_session_key;
+ base->acct_flags = pdb_get_acct_ctrl(sampw);
+
+ ZERO_STRUCT(user_session_key);
+ ZERO_STRUCT(lm_session_key);
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ inits a netr_SamInfo2 structure from an auth_serversupplied_info. sam2 must
+ already be initialized and is used as the talloc parent for its members.
+*****************************************************************************/
+
+NTSTATUS serverinfo_to_SamInfo2(struct auth_serversupplied_info *server_info,
+ uint8_t *pipe_session_key,
+ size_t pipe_session_key_len,
+ struct netr_SamInfo2 *sam2)
+{
+ NTSTATUS status;
+
+ status = serverinfo_to_SamInfo_base(sam2,
+ server_info,
+ pipe_session_key,
+ pipe_session_key_len,
+ &sam2->base);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ inits a netr_SamInfo3 structure from an auth_serversupplied_info. sam3 must
+ already be initialized and is used as the talloc parent for its members.
+*****************************************************************************/
+
+NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
+ uint8_t *pipe_session_key,
+ size_t pipe_session_key_len,
+ struct netr_SamInfo3 *sam3)
+{
+ NTSTATUS status;
+
+ status = serverinfo_to_SamInfo_base(sam3,
+ server_info,
+ pipe_session_key,
+ pipe_session_key_len,
+ &sam3->base);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ sam3->sidcount = 0;
+ sam3->sids = NULL;
+
+ return NT_STATUS_OK;
+}