svn commit: samba r17856 - in branches/SAMBA_4_0/source/libnet: .

mimir at samba.org mimir at samba.org
Sun Aug 27 20:37:24 GMT 2006


Author: mimir
Date: 2006-08-27 20:37:23 +0000 (Sun, 27 Aug 2006)
New Revision: 17856

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=17856

Log:
The two new functions - libnet_LookupName and libnet_UserInfo.
These two perform name resolving in SAM database and fetching
user account information, respectively. The code is quite rough
yet, but it builds and basic tests work. Now, I'm working on
cleaning it up...


rafal


Modified:
   branches/SAMBA_4_0/source/libnet/libnet_domain.c
   branches/SAMBA_4_0/source/libnet/libnet_lookup.c
   branches/SAMBA_4_0/source/libnet/libnet_lookup.h
   branches/SAMBA_4_0/source/libnet/libnet_user.c
   branches/SAMBA_4_0/source/libnet/libnet_user.h


Changeset:
Modified: branches/SAMBA_4_0/source/libnet/libnet_domain.c
===================================================================
--- branches/SAMBA_4_0/source/libnet/libnet_domain.c	2006-08-27 17:36:17 UTC (rev 17855)
+++ branches/SAMBA_4_0/source/libnet/libnet_domain.c	2006-08-27 20:37:23 UTC (rev 17856)
@@ -645,6 +645,7 @@
 	if (NT_STATUS_IS_OK(status) && io) {
 		ctx->lsa.name = NULL;
 		ZERO_STRUCT(ctx->lsa.handle);
+
 		io->out.error_string = talloc_asprintf(mem_ctx, "Success");
 
 	} else if (!NT_STATUS_IS_OK(status)) {

Modified: branches/SAMBA_4_0/source/libnet/libnet_lookup.c
===================================================================
--- branches/SAMBA_4_0/source/libnet/libnet_lookup.c	2006-08-27 17:36:17 UTC (rev 17855)
+++ branches/SAMBA_4_0/source/libnet/libnet_lookup.c	2006-08-27 20:37:23 UTC (rev 17856)
@@ -26,10 +26,14 @@
 #include "lib/events/events.h"
 #include "libnet/libnet.h"
 #include "libcli/composite/composite.h"
+#include "auth/credentials/credentials.h"
 #include "lib/messaging/messaging.h"
 #include "lib/messaging/irpc.h"
 #include "libcli/resolve/resolve.h"
 #include "libcli/finddcs.h"
+#include "libcli/security/security.h"
+#include "librpc/gen_ndr/lsa.h"
+#include "librpc/gen_ndr/ndr_lsa_c.h"
 
 struct lookup_state {
 	struct nbt_name hostname;
@@ -222,6 +226,46 @@
 	return status;
 }
 
+
+static struct composite_context* lsa_policy_opened(struct libnet_context *ctx,
+						   const char *domain_name,
+						   struct composite_context *parent_ctx,
+						   struct libnet_DomainOpen *domain_open,
+						   void (*continue_fn)(struct composite_context*),
+						   void (*monitor)(struct monitor_msg*))
+{
+	struct composite_context *domopen_req;
+
+	if (domain_name == NULL) {
+		if (policy_handle_empty(&ctx->lsa.handle)) {
+			domain_open->in.type        = DOMAIN_LSA;
+			domain_open->in.domain_name = cli_credentials_get_domain(ctx->cred);
+			domain_open->in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+
+		} else {
+			composite_error(parent_ctx, NT_STATUS_INVALID_PARAMETER);
+			return parent_ctx;
+		}
+	} else {
+		if (policy_handle_empty(&ctx->lsa.handle) ||
+		    !strequal(domain_name, ctx->lsa.name)) {
+			domain_open->in.type        = DOMAIN_LSA;
+			domain_open->in.domain_name = domain_name;
+			domain_open->in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+
+		} else {
+			return NULL;
+		}
+	}
+
+	domopen_req = libnet_DomainOpen_send(ctx, domain_open, monitor);
+	if (composite_nomem(domopen_req, parent_ctx)) return parent_ctx;
+
+	composite_continue(parent_ctx, domopen_req, continue_fn, parent_ctx);
+	return parent_ctx;
+}
+
+
 /**
  * Synchronous version of LookupDCs
  */
@@ -231,3 +275,174 @@
 	struct composite_context *c = libnet_LookupDCs_send(ctx, mem_ctx, io);
 	return libnet_LookupDCs_recv(c, mem_ctx, io);
 }
+
+
+struct lookup_name_state {
+	struct libnet_context *ctx;
+	const char *name;
+	uint32_t count;
+	struct libnet_DomainOpen domopen;
+	struct lsa_LookupNames lookup;
+	struct lsa_TransSidArray sids;
+	struct lsa_String *names;
+
+	/* information about the progress */
+	void (*monitor_fn)(struct monitor_msg *);
+};
+
+
+static bool prepare_lookup_params(struct libnet_context *ctx,
+				  struct composite_context *c,
+				  struct lookup_name_state *s);
+static void continue_lookup_name(struct composite_context *ctx);
+static void continue_name_found(struct rpc_request *req);
+
+
+struct composite_context* libnet_LookupName_send(struct libnet_context *ctx,
+						 TALLOC_CTX *mem_ctx,
+						 struct libnet_LookupName *io,
+						 void (*monitor)(struct monitor_msg*))
+{
+	struct composite_context *c;
+	struct lookup_name_state *s;
+	struct composite_context *prereq_ctx;
+	struct rpc_request *lookup_req;
+
+	c = composite_create(mem_ctx, ctx->event_ctx);
+	if (c == NULL) return NULL;
+
+	s = talloc_zero(c, struct lookup_name_state);
+	if (composite_nomem(s, c)) return c;
+
+	c->private_data = s;
+	
+	s->name = talloc_strdup(c, io->in.name);
+	s->monitor_fn = monitor;
+	s->ctx = ctx;
+
+	prereq_ctx = lsa_policy_opened(ctx, io->in.domain_name, c, &s->domopen,
+				       continue_lookup_name, monitor);
+	if (prereq_ctx) return prereq_ctx;
+
+	if (!prepare_lookup_params(ctx, c, s)) return c;
+
+	lookup_req = dcerpc_lsa_LookupNames_send(ctx->lsa.pipe, c, &s->lookup);
+	if (composite_nomem(lookup_req, c)) return c;
+
+	composite_continue_rpc(c, lookup_req, continue_name_found, c);
+	return c;
+}
+
+
+static bool prepare_lookup_params(struct libnet_context *ctx,
+				  struct composite_context *c,
+				  struct lookup_name_state *s)
+{
+	const int single_name = 1;
+
+	s->sids.count = 0;
+	s->sids.sids  = NULL;
+	
+	s->names = talloc_array(ctx, struct lsa_String, single_name);
+	if (composite_nomem(s->names, c)) return false;
+	s->names[0].string = s->name;
+	
+	s->lookup.in.handle    = &ctx->lsa.handle;
+	s->lookup.in.num_names = single_name;
+	s->lookup.in.names     = s->names;
+	s->lookup.in.sids      = &s->sids;
+	s->lookup.in.level     = 1;
+	s->lookup.in.count     = &s->count;
+	s->lookup.out.count    = &s->count;
+	s->lookup.out.sids     = &s->sids;
+	
+	return true;
+}
+
+
+static void continue_lookup_name(struct composite_context *ctx)
+{
+	struct composite_context *c;
+	struct lookup_name_state *s;
+	struct rpc_request *lookup_req;
+
+	c = talloc_get_type(ctx->async.private_data, struct composite_context);
+	s = talloc_get_type(c->private_data, struct lookup_name_state);
+
+	c->status = libnet_DomainOpen_recv(ctx, s->ctx, c, &s->domopen);
+	if (!composite_is_ok(c)) return;
+	
+	if (!prepare_lookup_params(s->ctx, c, s)) return;
+
+	lookup_req = dcerpc_lsa_LookupNames_send(s->ctx->lsa.pipe, c, &s->lookup);
+	if (composite_nomem(lookup_req, c)) return;
+	
+	composite_continue_rpc(c, lookup_req, continue_name_found, c);
+}
+
+
+static void continue_name_found(struct rpc_request *req)
+{
+	struct composite_context *c;
+	struct lookup_name_state *s;
+
+	c = talloc_get_type(req->async.private, struct composite_context);
+	s = talloc_get_type(c->private_data, struct lookup_name_state);
+
+	c->status = dcerpc_ndr_request_recv(req);
+	if (!composite_is_ok(c)) return;
+
+	composite_done(c);
+}
+
+
+NTSTATUS libnet_LookupName_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
+				struct libnet_LookupName *io)
+{
+	NTSTATUS status;
+	struct lookup_name_state *s;
+
+	status = composite_wait(c);
+
+	if (NT_STATUS_IS_OK(status)) {
+		s = talloc_get_type(c->private_data, struct lookup_name_state);
+		
+		ZERO_STRUCT(io->out.domain_sid);
+		io->out.rid = 0;
+		io->out.sidstr = NULL;
+
+		if (*s->lookup.out.count > 0) {
+			int num_auths;
+			struct lsa_RefDomainList *domains = s->lookup.out.domains;
+			struct lsa_TransSidArray *sids = s->lookup.out.sids;
+
+			/* TODO: verify if returned pointers are non-null */
+
+			io->out.domain_sid = *domains->domains[0].sid;
+			io->out.rid        = sids->sids[0].rid;
+			io->out.sid_type   = sids->sids[0].sid_type;
+
+			num_auths = io->out.domain_sid.num_auths++;
+			io->out.domain_sid.sub_auths[num_auths] = io->out.rid;
+
+			io->out.sidstr     = dom_sid_string(mem_ctx, &io->out.domain_sid);
+		}
+
+		io->out.error_string = talloc_strdup(mem_ctx, "Success");
+
+	} else if (!NT_STATUS_IS_OK(status)) {
+		io->out.error_string = talloc_asprintf(mem_ctx, "Error: %s", nt_errstr(status));
+	}
+
+	return status;
+}
+
+
+NTSTATUS libnet_LookupName(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
+			   struct libnet_LookupName *io)
+{
+	struct composite_context *c;
+	
+	c = libnet_LookupName_send(ctx, mem_ctx, io, NULL);
+	return libnet_LookupName_recv(c, mem_ctx, io);
+}

Modified: branches/SAMBA_4_0/source/libnet/libnet_lookup.h
===================================================================
--- branches/SAMBA_4_0/source/libnet/libnet_lookup.h	2006-08-27 17:36:17 UTC (rev 17855)
+++ branches/SAMBA_4_0/source/libnet/libnet_lookup.h	2006-08-27 20:37:23 UTC (rev 17856)
@@ -30,6 +30,7 @@
 	} out;
 };
 
+
 struct libnet_LookupDCs {
 	struct {
 		const char *domain_name;
@@ -40,3 +41,18 @@
 		struct nbt_dc_name *dcs;
 	} out;
 };
+
+
+struct libnet_LookupName {
+	struct {
+		const char *name;
+		const char *domain_name;
+	} in;
+	struct {
+		struct dom_sid domain_sid;
+		int rid;
+		enum lsa_SidType sid_type;
+		const char *sidstr;
+		const char *error_string;
+	} out;
+};

Modified: branches/SAMBA_4_0/source/libnet/libnet_user.c
===================================================================
--- branches/SAMBA_4_0/source/libnet/libnet_user.c	2006-08-27 17:36:17 UTC (rev 17855)
+++ branches/SAMBA_4_0/source/libnet/libnet_user.c	2006-08-27 20:37:23 UTC (rev 17856)
@@ -613,3 +613,160 @@
 	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;
+	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_opened(struct composite_context *ctx);
+static void continue_info_received(struct composite_context *ctx);
+
+
+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;
+
+	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;
+
+	s->monitor_fn = monitor;
+	s->ctx = ctx;
+	s->domain_name = talloc_strdup(c, r->in.domain_name);
+
+	s->lookup.in.domain_name = s->domain_name;
+	s->lookup.in.name        = talloc_strdup(c, r->in.user_name);
+
+	lookup_req = libnet_LookupName_send(ctx, c, &s->lookup, s->monitor_fn);
+	if (composite_nomem(lookup_req, c)) return c;
+
+	composite_continue(c, lookup_req, continue_name_found, c);
+	return c;
+}
+
+
+static void continue_name_found(struct composite_context *ctx)
+{
+	struct composite_context *c;
+	struct user_info_state *s;
+	struct composite_context *domopen_req;
+
+	c = talloc_get_type(ctx->async.private_data, struct composite_context);
+	s = talloc_get_type(c->private_data, struct user_info_state);
+
+	c->status = libnet_LookupName_recv(ctx, c, &s->lookup);
+	if (!composite_is_ok(c)) return;
+
+	if (s->lookup.out.sid_type != SID_NAME_USER) {
+		composite_error(c, NT_STATUS_NO_SUCH_USER);
+		return;
+	}
+
+	s->domopen.in.type = DOMAIN_SAMR;
+	s->domopen.in.domain_name = s->domain_name;
+	s->domopen.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+
+	domopen_req = libnet_DomainOpen_send(s->ctx, &s->domopen, s->monitor_fn);
+	if (composite_nomem(domopen_req, c)) return;
+	
+	composite_continue(c, domopen_req, continue_domain_opened, c);
+}
+
+
+static void continue_domain_opened(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);
+
+	c->status = libnet_DomainOpen_recv(ctx, s->ctx, c, &s->domopen);
+	if (!composite_is_ok(c)) return;
+
+	s->userinfo.in.domain_handle = s->ctx->samr.handle;
+	s->userinfo.in.sid = s->lookup.out.sidstr;
+	s->userinfo.in.level = 21;
+
+	info_req = libnet_rpc_userinfo_send(s->ctx->samr.pipe, &s->userinfo, s->monitor_fn);
+	if (composite_nomem(info_req, c)) return;
+
+	composite_continue(c, info_req, continue_info_received, c);
+}
+
+
+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);
+	
+	c->status = libnet_rpc_userinfo_recv(ctx, c, &s->userinfo);
+	if (!composite_is_ok(c)) return;
+
+	composite_done(c);
+}
+
+
+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.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);
+
+		r->out.error_string = talloc_strdup(mem_ctx, "Success");
+	}
+
+	talloc_free(c);
+	
+	return 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);
+}

Modified: branches/SAMBA_4_0/source/libnet/libnet_user.h
===================================================================
--- branches/SAMBA_4_0/source/libnet/libnet_user.h	2006-08-27 17:36:17 UTC (rev 17855)
+++ branches/SAMBA_4_0/source/libnet/libnet_user.h	2006-08-27 20:37:23 UTC (rev 17856)
@@ -87,3 +87,30 @@
 			mod->fields |= flag; \
 		} \
 	}
+
+
+struct libnet_UserInfo {
+	struct {
+		const char *user_name;
+		const char *domain_name;
+	} in;
+	struct {
+		const char *account_name;
+		const char *full_name;
+		const char *description;
+		const char *home_directory;
+		const char *home_drive;
+		const char *comment;
+		const char *logon_script;
+		const char *profile_path;
+		struct timeval *acct_expiry;
+		struct timeval *allow_password_change;
+		struct timeval *force_password_change;
+		struct timeval *last_logon;
+		struct timeval *last_logoff;
+		struct timeval *last_password_change;
+		uint32_t acct_flags;
+		
+		const char *error_string;
+	} out;
+};



More information about the samba-cvs mailing list