libnet_user.c

来自「samba最新软件」· C语言 代码 · 共 1,198 行 · 第 1/3 页

C
1,198
字号
	const uint16_t level = 21;	struct composite_context *c;	struct modify_user_state *s;	struct composite_context *userinfo_req;	bool prereq_met = false;	c = composite_create(mem_ctx, ctx->event_ctx);	if (c == NULL) return NULL;	s = talloc_zero(c, struct modify_user_state);	if (composite_nomem(s, c)) return c;	c->private_data = s;	s->ctx = ctx;	s->r = *r;	prereq_met = samr_domain_opened(ctx, s->r.in.domain_name, &c, &s->domain_open,					continue_domain_open_modify, monitor);	if (!prereq_met) return c;	s->user_info.in.username      = r->in.user_name;	s->user_info.in.domain_handle = ctx->samr.handle;	s->user_info.in.level         = level;	userinfo_req = libnet_rpc_userinfo_send(ctx->samr.pipe, &s->user_info, monitor);	if (composite_nomem(userinfo_req, c)) return c;	composite_continue(c, userinfo_req, continue_rpc_userinfo, c);	return c;}/* * Stage 0.5 (optional): receive result of domain open request * and send userinfo request */static void continue_domain_open_modify(struct composite_context *ctx){	const uint16_t level = 21;	struct composite_context *c;	struct modify_user_state *s;	struct composite_context *userinfo_req;	struct monitor_msg msg;	c = talloc_get_type(ctx->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct modify_user_state);	c->status = libnet_DomainOpen_recv(ctx, s->ctx, c, &s->domain_open);	if (!composite_is_ok(c)) return;	if (s->monitor_fn) s->monitor_fn(&msg);		s->user_info.in.domain_handle  = s->ctx->samr.handle;	s->user_info.in.username       = s->r.in.user_name;	s->user_info.in.level          = level;	userinfo_req = libnet_rpc_userinfo_send(s->ctx->samr.pipe, &s->user_info, s->monitor_fn);	if (composite_nomem(userinfo_req, c)) return;		composite_continue(c, userinfo_req, continue_rpc_userinfo, c);}/* * Stage 1: receive result of userinfo call, prepare user changes * (set the fields a caller required to change) and send usermod request */static void continue_rpc_userinfo(struct composite_context *ctx){	struct composite_context *c;	struct modify_user_state *s;	struct composite_context *usermod_req;	c = talloc_get_type(ctx->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct modify_user_state);	c->status = libnet_rpc_userinfo_recv(ctx, c, &s->user_info);	if (!composite_is_ok(c)) return;	s->user_mod.in.domain_handle = s->ctx->samr.handle;	s->user_mod.in.username      = s->r.in.user_name;	c->status = set_user_changes(c, &s->user_mod.in.change, &s->user_info, &s->r);	usermod_req = libnet_rpc_usermod_send(s->ctx->samr.pipe, &s->user_mod, s->monitor_fn);	if (composite_nomem(usermod_req, c)) return;	composite_continue(c, usermod_req, continue_rpc_usermod, c);}/* * Prepare user changes: compare userinfo result to requested changes and * set the field values and flags accordingly for user modify call */static NTSTATUS set_user_changes(TALLOC_CTX *mem_ctx, struct usermod_change *mod,				 struct libnet_rpc_userinfo *info, struct libnet_ModifyUser *r){	struct samr_UserInfo21 *user;	if (mod == NULL || info == NULL || r == NULL || info->in.level != 21) {		return NT_STATUS_INVALID_PARAMETER;	}	user = &info->out.info.info21;	mod->fields = 0;        /* reset flag field before setting individual flags */	/* account name change */	SET_FIELD_LSA_STRING(r->in, user, mod, account_name, USERMOD_FIELD_ACCOUNT_NAME);	/* full name change */	SET_FIELD_LSA_STRING(r->in, user, mod, full_name, USERMOD_FIELD_FULL_NAME);	/* description change */	SET_FIELD_LSA_STRING(r->in, user, mod, description, USERMOD_FIELD_DESCRIPTION);	/* comment change */	SET_FIELD_LSA_STRING(r->in, user, mod, comment, USERMOD_FIELD_COMMENT);	/* home directory change */	SET_FIELD_LSA_STRING(r->in, user, mod, home_directory, USERMOD_FIELD_HOME_DIRECTORY);	/* home drive change */	SET_FIELD_LSA_STRING(r->in, user, mod, home_drive, USERMOD_FIELD_HOME_DRIVE);	/* logon script change */	SET_FIELD_LSA_STRING(r->in, user, mod, logon_script, USERMOD_FIELD_LOGON_SCRIPT);	/* profile path change */	SET_FIELD_LSA_STRING(r->in, user, mod, profile_path, USERMOD_FIELD_PROFILE_PATH);	/* account expiry change */	SET_FIELD_NTTIME(r->in, user, mod, acct_expiry, USERMOD_FIELD_ACCT_EXPIRY);	/* account flags change */	SET_FIELD_ACCT_FLAGS(r->in, user, mod, acct_flags, USERMOD_FIELD_ACCT_FLAGS);	return NT_STATUS_OK;}/* * Stage 2: receive result of usermod request and finish the composite function */static void continue_rpc_usermod(struct composite_context *ctx){	struct composite_context *c;	struct modify_user_state *s;	struct monitor_msg msg;	c = talloc_get_type(ctx->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct modify_user_state);		c->status = libnet_rpc_usermod_recv(ctx, c, &s->user_mod);	if (!composite_is_ok(c)) return;		if (s->monitor_fn) s->monitor_fn(&msg);	composite_done(c);}/** * Receive result of ModifyUser call * * @param c composite context returned by send request routine * @param mem_ctx memory context of this call * @param r pointer to a structure containing arguments and result of this call * @return nt status */NTSTATUS libnet_ModifyUser_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,				struct libnet_ModifyUser *r){	NTSTATUS status = composite_wait(c);	return status;}/** * Synchronous version of ModifyUser call * * @param ctx initialised libnet context * @param mem_ctx memory context of this call * @param r pointer to a structure containing arguments and result of this call * @return nt status */NTSTATUS libnet_ModifyUser(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,			   struct libnet_ModifyUser *r){	struct composite_context *c;	c = libnet_ModifyUser_send(ctx, mem_ctx, r, NULL);	return libnet_ModifyUser_recv(c, mem_ctx, r);}struct user_info_state {	struct libnet_context *ctx;	const char *domain_name;	enum libnet_UserInfo_level level;	const char *user_name;	const char *sid_string;	struct libnet_LookupName lookup;	struct libnet_DomainOpen domopen;	struct libnet_rpc_userinfo userinfo;	/* information about the progress */	void (*monitor_fn)(struct monitor_msg *);};static void continue_name_found(struct composite_context *ctx);static void continue_domain_open_info(struct composite_context *ctx);static void continue_info_received(struct composite_context *ctx);/** * Sends request to get user account information * * @param ctx initialised libnet context * @param mem_ctx memory context of this call * @param r pointer to a structure containing arguments and results of this call * @param monitor function pointer for receiving monitor messages * @return compostite context of this request */struct composite_context* libnet_UserInfo_send(struct libnet_context *ctx,					       TALLOC_CTX *mem_ctx,					       struct libnet_UserInfo *r,					       void (*monitor)(struct monitor_msg*)){	struct composite_context *c;	struct user_info_state *s;	struct composite_context *lookup_req, *info_req;	bool prereq_met = false;	/* composite context allocation and setup */	c = composite_create(mem_ctx, ctx->event_ctx);	if (c == NULL) return NULL;	s = talloc_zero(c, struct user_info_state);	if (composite_nomem(s, c)) return c;	c->private_data = s;	/* store arguments in the state structure */	s->monitor_fn = monitor;	s->ctx = ctx;	s->domain_name = talloc_strdup(c, r->in.domain_name);	s->level = r->in.level;	switch (s->level) {	case USER_INFO_BY_NAME:		s->user_name = talloc_strdup(c, r->in.data.user_name);		s->sid_string = NULL;		break;	case USER_INFO_BY_SID:		s->user_name = NULL;		s->sid_string = dom_sid_string(c, r->in.data.user_sid);		break;	}	/* prerequisite: make sure the domain is opened */	prereq_met = samr_domain_opened(ctx, s->domain_name, &c, &s->domopen,					continue_domain_open_info, monitor);	if (!prereq_met) return c;	switch (s->level) {	case USER_INFO_BY_NAME:		/* prepare arguments for LookupName call */		s->lookup.in.domain_name = s->domain_name;		s->lookup.in.name        = s->user_name;		/* send the request */		lookup_req = libnet_LookupName_send(ctx, c, &s->lookup,						    s->monitor_fn);		if (composite_nomem(lookup_req, c)) return c;		/* set the next stage */		composite_continue(c, lookup_req, continue_name_found, c);		break;	case USER_INFO_BY_SID:		/* prepare arguments for UserInfo call */		s->userinfo.in.domain_handle = s->ctx->samr.handle;		s->userinfo.in.sid = s->sid_string;		s->userinfo.in.level = 21;		/* send the request */		info_req = libnet_rpc_userinfo_send(s->ctx->samr.pipe,						    &s->userinfo,						    s->monitor_fn);		if (composite_nomem(info_req, c)) return c;		/* set the next stage */		composite_continue(c, info_req, continue_info_received, c);		break;	}	return c;}/* * Stage 0.5 (optional): receive result of domain open request * and send LookupName request */static void continue_domain_open_info(struct composite_context *ctx){	struct composite_context *c;	struct user_info_state *s;	struct composite_context *lookup_req, *info_req;	struct monitor_msg msg;	c = talloc_get_type(ctx->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct user_info_state);	/* receive result of DomainOpen call */	c->status = libnet_DomainOpen_recv(ctx, s->ctx, c, &s->domopen);	if (!composite_is_ok(c)) return;	/* send monitor message */	if (s->monitor_fn) s->monitor_fn(&msg);	switch (s->level) {	case USER_INFO_BY_NAME:		/* prepare arguments for LookupName call */		s->lookup.in.domain_name = s->domain_name;		s->lookup.in.name        = s->user_name;		/* send the request */		lookup_req = libnet_LookupName_send(s->ctx, c, &s->lookup, s->monitor_fn);		if (composite_nomem(lookup_req, c)) return;		/* set the next stage */		composite_continue(c, lookup_req, continue_name_found, c);		break;	case USER_INFO_BY_SID:		/* prepare arguments for UserInfo call */		s->userinfo.in.domain_handle = s->ctx->samr.handle;		s->userinfo.in.sid = s->sid_string;		s->userinfo.in.level = 21;		/* send the request */		info_req = libnet_rpc_userinfo_send(s->ctx->samr.pipe,						    &s->userinfo,						    s->monitor_fn);		if (composite_nomem(info_req, c)) return;		/* set the next stage */		composite_continue(c, info_req, continue_info_received, c);		break;	}}/* * Stage 1: receive the name (if found) and send userinfo request */static void continue_name_found(struct composite_context *ctx){	struct composite_context *c;	struct user_info_state *s;	struct composite_context *info_req;	c = talloc_get_type(ctx->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct user_info_state);	/* receive result of LookupName call */	c->status = libnet_LookupName_recv(ctx, c, &s->lookup);	if (!composite_is_ok(c)) return;	/* we're only interested in user accounts this time */	if (s->lookup.out.sid_type != SID_NAME_USER) {		composite_error(c, NT_STATUS_NO_SUCH_USER);		return;	}	/* prepare arguments for UserInfo call */	s->userinfo.in.domain_handle = s->ctx->samr.handle;	s->userinfo.in.sid = s->lookup.out.sidstr;	s->userinfo.in.level = 21;	/* send the request */	info_req = libnet_rpc_userinfo_send(s->ctx->samr.pipe, &s->userinfo, s->monitor_fn);	if (composite_nomem(info_req, c)) return;	/* set the next stage */	composite_continue(c, info_req, continue_info_received, c);}/* * Stage 2: receive user account information and finish the composite function */static void continue_info_received(struct composite_context *ctx){	struct composite_context *c;	struct user_info_state *s;	c = talloc_get_type(ctx->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct user_info_state);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?