libnet_user.c

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

C
1,198
字号
		/* receive result of userinfo call */	c->status = libnet_rpc_userinfo_recv(ctx, c, &s->userinfo);	if (!composite_is_ok(c)) return;	composite_done(c);}/** * Receive result of UserInfo 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_UserInfo_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,			      struct libnet_UserInfo *r){	NTSTATUS status;	struct user_info_state *s;	status = composite_wait(c);	if (NT_STATUS_IS_OK(status) && r != NULL) {		struct samr_UserInfo21 *info;		s = talloc_get_type(c->private_data, struct user_info_state);		info = &s->userinfo.out.info.info21;		r->out.user_sid = dom_sid_add_rid(mem_ctx, s->ctx->samr.sid, info->rid);		r->out.primary_group_sid = dom_sid_add_rid(mem_ctx, s->ctx->samr.sid, info->primary_gid);		/* string fields */		r->out.account_name   = talloc_steal(mem_ctx, info->account_name.string);		r->out.full_name      = talloc_steal(mem_ctx, info->full_name.string);		r->out.description    = talloc_steal(mem_ctx, info->description.string);		r->out.home_directory = talloc_steal(mem_ctx, info->home_directory.string);		r->out.home_drive     = talloc_steal(mem_ctx, info->home_drive.string);		r->out.comment        = talloc_steal(mem_ctx, info->comment.string);		r->out.logon_script   = talloc_steal(mem_ctx, info->logon_script.string);		r->out.profile_path   = talloc_steal(mem_ctx, info->profile_path.string);		/* time fields (allocation) */		r->out.acct_expiry           = talloc(mem_ctx, struct timeval);		r->out.allow_password_change = talloc(mem_ctx, struct timeval);		r->out.force_password_change = talloc(mem_ctx, struct timeval);		r->out.last_logon            = talloc(mem_ctx, struct timeval);		r->out.last_logoff           = talloc(mem_ctx, struct timeval);		r->out.last_password_change  = talloc(mem_ctx, struct timeval);				/* time fields (converting) */		nttime_to_timeval(r->out.acct_expiry, info->acct_expiry);		nttime_to_timeval(r->out.allow_password_change, info->allow_password_change);		nttime_to_timeval(r->out.force_password_change, info->force_password_change);		nttime_to_timeval(r->out.last_logon, info->last_logon);		nttime_to_timeval(r->out.last_logoff, info->last_logoff);		nttime_to_timeval(r->out.last_password_change, info->last_password_change);		/* flag and number fields */		r->out.acct_flags = info->acct_flags;		r->out.error_string = talloc_strdup(mem_ctx, "Success");	} else {		r->out.error_string = talloc_asprintf(mem_ctx, "Error: %s", nt_errstr(status));	}	talloc_free(c);		return status;}/** * Synchronous version of UserInfo 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_UserInfo(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,			 struct libnet_UserInfo *r){	struct composite_context *c;		c = libnet_UserInfo_send(ctx, mem_ctx, r, NULL);	return libnet_UserInfo_recv(c, mem_ctx, r);}struct userlist_state {	struct libnet_context *ctx;	const char *domain_name;	struct lsa_DomainInfo dominfo;	int page_size;	uint32_t resume_index;	struct userlist *users;	uint32_t count;	struct libnet_DomainOpen domain_open;	struct lsa_QueryInfoPolicy query_domain;	struct samr_EnumDomainUsers user_list;	void (*monitor_fn)(struct monitor_msg*);};static void continue_lsa_domain_opened(struct composite_context *ctx);static void continue_domain_queried(struct rpc_request *req);static void continue_samr_domain_opened(struct composite_context *ctx);static void continue_users_enumerated(struct rpc_request *req);/** * Sends request to list (enumerate) user accounts * * @param ctx initialised libnet context * @param mem_ctx memory context of this call * @param r pointer to 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_UserList_send(struct libnet_context *ctx,					       TALLOC_CTX *mem_ctx,					       struct libnet_UserList *r,					       void (*monitor)(struct monitor_msg*)){	struct composite_context *c;	struct userlist_state *s;	struct rpc_request *query_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 userlist_state);	if (composite_nomem(s, c)) return c;	c->private_data = s;	/* store the arguments in the state structure */	s->ctx          = ctx;	s->page_size    = r->in.page_size;	s->resume_index = (uint32_t)r->in.resume_index;	s->domain_name  = talloc_strdup(c, r->in.domain_name);	s->monitor_fn   = monitor;	/* make sure we have lsa domain handle before doing anything */	prereq_met = lsa_domain_opened(ctx, s->domain_name, &c, &s->domain_open,				       continue_lsa_domain_opened, monitor);	if (!prereq_met) return c;	/* prepare arguments of QueryDomainInfo call */	s->query_domain.in.handle = &ctx->lsa.handle;	s->query_domain.in.level  = LSA_POLICY_INFO_DOMAIN;		/* send the request */	query_req = dcerpc_lsa_QueryInfoPolicy_send(ctx->lsa.pipe, c, &s->query_domain);	if (composite_nomem(query_req, c)) return c;	composite_continue_rpc(c, query_req, continue_domain_queried, c);	return c;}/* * Stage 0.5 (optional): receive lsa domain handle and send * request to query domain info */static void continue_lsa_domain_opened(struct composite_context *ctx){	struct composite_context *c;	struct userlist_state *s;	struct rpc_request *query_req;		c = talloc_get_type(ctx->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct userlist_state);		/* receive lsa domain handle */	c->status = libnet_DomainOpen_recv(ctx, s->ctx, c, &s->domain_open);	if (!composite_is_ok(c)) return;	/* prepare arguments of QueryDomainInfo call */	s->query_domain.in.handle = &s->ctx->lsa.handle;	s->query_domain.in.level  = LSA_POLICY_INFO_DOMAIN;	/* send the request */	query_req = dcerpc_lsa_QueryInfoPolicy_send(s->ctx->lsa.pipe, c, &s->query_domain);	if (composite_nomem(query_req, c)) return;	composite_continue_rpc(c, query_req, continue_domain_queried, c);}/* * Stage 1: receive domain info and request to enum users, * provided a valid samr handle is opened */static void continue_domain_queried(struct rpc_request *req){	struct composite_context *c;	struct userlist_state *s;	struct rpc_request *enum_req;	bool prereq_met = false;		c = talloc_get_type(req->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct userlist_state);	/* receive result of rpc request */	c->status = dcerpc_ndr_request_recv(req);	if (!composite_is_ok(c)) return;	/* get the returned domain info */	s->dominfo = s->query_domain.out.info->domain;	/* make sure we have samr domain handle before continuing */	prereq_met = samr_domain_opened(s->ctx, s->domain_name, &c, &s->domain_open,					continue_samr_domain_opened, s->monitor_fn);	if (!prereq_met) return;	/* prepare arguments of EnumDomainUsers call */	s->user_list.in.domain_handle = &s->ctx->samr.handle;	s->user_list.in.max_size = s->page_size;	s->user_list.in.resume_handle = &s->resume_index;	s->user_list.in.acct_flags = ACB_NORMAL;	s->user_list.out.resume_handle = &s->resume_index;	/* send the request */	enum_req = dcerpc_samr_EnumDomainUsers_send(s->ctx->samr.pipe, c, &s->user_list);	if (composite_nomem(enum_req, c)) return;	composite_continue_rpc(c, enum_req, continue_users_enumerated, c);}/* * Stage 1.5 (optional): receive samr domain handle * and request to enumerate accounts */static void continue_samr_domain_opened(struct composite_context *ctx){	struct composite_context *c;	struct userlist_state *s;	struct rpc_request *enum_req;	c = talloc_get_type(ctx->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct userlist_state);	/* receive samr domain handle */	c->status = libnet_DomainOpen_recv(ctx, s->ctx, c, &s->domain_open);	if (!composite_is_ok(c)) return;	/* prepare arguments of EnumDomainUsers call */	s->user_list.in.domain_handle = &s->ctx->samr.handle;	s->user_list.in.max_size = s->page_size;	s->user_list.in.resume_handle = &s->resume_index;	s->user_list.in.acct_flags = ACB_NORMAL;	s->user_list.out.resume_handle = &s->resume_index;		/* send the request */	enum_req = dcerpc_samr_EnumDomainUsers_send(s->ctx->samr.pipe, c, &s->user_list);	if (composite_nomem(enum_req, c)) return;	composite_continue_rpc(c, enum_req, continue_users_enumerated, c);}/* * Stage 2: receive enumerated users and their rids */static void continue_users_enumerated(struct rpc_request *req){	struct composite_context *c;	struct userlist_state *s;	int i;	c = talloc_get_type(req->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct userlist_state);	/* receive result of rpc request */	c->status = dcerpc_ndr_request_recv(req);	if (!composite_is_ok(c)) return;	/* get the actual status of the rpc call result	   (instead of rpc layer status) */	c->status = s->user_list.out.result;	/* we're interested in status "ok" as well as two	   enum-specific status codes */	if (NT_STATUS_IS_OK(c->status) ||	    NT_STATUS_EQUAL(c->status, STATUS_MORE_ENTRIES) ||	    NT_STATUS_EQUAL(c->status, NT_STATUS_NO_MORE_ENTRIES)) {		/* get enumerated accounts counter and resume handle (the latter allows		   making subsequent call to continue enumeration) */		s->resume_index = *s->user_list.out.resume_handle;		s->count        = s->user_list.out.num_entries;				/* prepare returned user accounts array */		s->users        = talloc_array(c, struct userlist, s->user_list.out.sam->count);		if (composite_nomem(s->users, c)) return;		for (i = 0; i < s->user_list.out.sam->count; i++) {			struct dom_sid *user_sid;			struct samr_SamEntry *entry = &s->user_list.out.sam->entries[i];			struct dom_sid *domain_sid = s->query_domain.out.info->domain.sid;						/* construct user sid from returned rid and queried domain sid */			user_sid = dom_sid_add_rid(c, domain_sid, entry->idx);			if (composite_nomem(user_sid, c)) return;						/* username */			s->users[i].username = talloc_strdup(c, entry->name.string);			if (composite_nomem(s->users[i].username, c)) return;			/* sid string */			s->users[i].sid = dom_sid_string(c, user_sid);			if (composite_nomem(s->users[i].sid, c)) return;		}				/* that's it */		composite_done(c);	} else {		/* something went wrong */		composite_error(c, c->status);	}}/** * Receive result of UserList call * * @param c composite context returned by send request routine * @param mem_ctx memory context of this call * @param r pointer to structure containing arguments and result of this call * @return nt status */NTSTATUS libnet_UserList_recv(struct composite_context* c, TALLOC_CTX *mem_ctx,			      struct libnet_UserList *r){	NTSTATUS status;	struct userlist_state *s;	if (c == NULL || mem_ctx == NULL || r == NULL) {		return NT_STATUS_INVALID_PARAMETER;	}		status = composite_wait(c);	if (NT_STATUS_IS_OK(status) ||	    NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||	    NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {				s = talloc_get_type(c->private_data, struct userlist_state);				/* get results from composite context */		r->out.count = s->count;		r->out.resume_index = s->resume_index;		r->out.users = talloc_steal(mem_ctx, s->users);				if (NT_STATUS_IS_OK(status)) {			r->out.error_string = talloc_strdup(mem_ctx, "Success");		} else {			/* success, but we're not done yet */			r->out.error_string = talloc_asprintf(mem_ctx, "Success (status: %s)",							      nt_errstr(status));		}	} else {		r->out.error_string = talloc_asprintf(mem_ctx, "Error: %s", nt_errstr(status));	}	return status;}/** * Synchronous version of UserList call * * @param ctx initialised libnet context * @param mem_ctx memory context of this call * @param r pointer to structure containing arguments and result of this call * @return nt status */NTSTATUS libnet_UserList(struct libnet_context *ctx,			 TALLOC_CTX *mem_ctx,			 struct libnet_UserList *r){	struct composite_context *c;	c = libnet_UserList_send(ctx, mem_ctx, r, NULL);	return libnet_UserList_recv(c, mem_ctx, r);}

⌨️ 快捷键说明

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