trusted domains patch number n+1

mimir at diament.ists.pwr.wroc.pl mimir at diament.ists.pwr.wroc.pl
Mon Jul 22 06:06:03 GMT 2002


Patch includes:
 - brand new trust relationships listing code, purely 
   in rpc-way
 - new cli_samr_enum_dom_users() function
 - slight fix to libsmb code (anonymous fallback in connecting
   ti IPC$)
 - a few typos

It's a little rough code and as such it needs some clean-ups yet.
However the main ways and ideas are visible ;)

any comments are appreciated


-- 
cheers,
+------------------------------------------------------------+
|Rafal 'Mimir' Szczesniak <mimir at diament.ists.pwr.wroc.pl>   |
|*BSD, GNU/Linux and Samba                                  /
|__________________________________________________________/
-------------- next part --------------
Index: source/lib/util_unistr.c
===================================================================
RCS file: /cvsroot/samba/source/lib/util_unistr.c,v
retrieving revision 1.93
diff -u -r1.93 util_unistr.c
--- source/lib/util_unistr.c	14 Apr 2002 09:44:14 -0000	1.93
+++ source/lib/util_unistr.c	22 Jul 2002 12:28:46 -0000
@@ -218,6 +218,29 @@
 	pull_ucs2(NULL, dest, str->buffer, maxlen, str->uni_str_len*2, STR_NOALIGN);
 }
 
+/**
+ * Convert smb_ucs2_t string to an ASCII string
+ *
+ * @param dest Destination ASCII string
+ * @param src Source UCS2 string
+ * @para maxlen maximum number of characters to be copied to dest
+ */
+char* ucs2_to_ascii(char *dest, const smb_ucs2_t *src, size_t maxlen)
+{
+	size_t src_len;
+	
+	if (src == NULL) {
+		*dest = '\0';
+		return dest;
+	}
+	
+	src_len = strlen_w(src);
+		
+	pull_ucs2(NULL, dest, src, maxlen, src_len * 2, STR_NOALIGN);
+	
+	return dest;
+}
+
 
 /*******************************************************************
  duplicate a UNISTR2 string into a null terminated char*
Index: source/libsmb/cli_lsarpc.c
===================================================================
RCS file: /cvsroot/samba/source/libsmb/cli_lsarpc.c,v
retrieving revision 1.46
diff -u -r1.46 cli_lsarpc.c
--- source/libsmb/cli_lsarpc.c	1 Jun 2002 00:10:08 -0000	1.46
+++ source/libsmb/cli_lsarpc.c	22 Jul 2002 12:28:47 -0000
@@ -543,7 +543,7 @@
 NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                                 POLICY_HND *pol, uint32 *enum_ctx, 
                                 uint32 *pref_num_domains, uint32 *num_domains,
-				char ***domain_names, DOM_SID **domain_sids)
+                                char ***domain_names, DOM_SID **domain_sids)
 {
 	prs_struct qbuf, rbuf;
 	LSA_Q_ENUM_TRUST_DOM q;
@@ -598,7 +598,7 @@
 
 		if (!*domain_names) {
 			DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
-			result = NT_STATUS_UNSUCCESSFUL;
+			result = NT_STATUS_NO_MEMORY;
 			goto done;
 		}
 
@@ -606,7 +606,7 @@
 						 r.num_domains);
 		if (!domain_sids) {
 			DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
-			result = NT_STATUS_UNSUCCESSFUL;
+			result = NT_STATUS_NO_MEMORY;
 			goto done;
 		}
 
@@ -631,6 +631,7 @@
 
 	return result;
 }
+
 
 /** Enumerate privileges*/
 
Index: source/libsmb/cli_samr.c
===================================================================
RCS file: /cvsroot/samba/source/libsmb/cli_samr.c,v
retrieving revision 1.31
diff -u -r1.31 cli_samr.c
--- source/libsmb/cli_samr.c	21 Jun 2002 17:23:18 -0000	1.31
+++ source/libsmb/cli_samr.c	22 Jul 2002 12:28:49 -0000
@@ -491,6 +491,97 @@
 	return result;
 }
 
+/* Enumerate domain users */
+NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                                 POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask,
+                                 uint32 size, char ***dom_users, uint32 **rids,
+                                 uint32 *num_dom_users)
+{
+	prs_struct qdata;
+	prs_struct rdata;
+	SAMR_Q_ENUM_DOM_USERS q;
+	SAMR_R_ENUM_DOM_USERS r;
+	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+	int i;
+	
+	ZERO_STRUCT(q);
+	ZERO_STRUCT(r);
+	
+	if (cli == NULL || pol == NULL)
+		return result;
+	
+	/* initialise parse structures */
+	prs_init(&qdata, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+	prs_init(&rdata, 0, mem_ctx, UNMARSHALL);
+	
+	DEBUG(4, ("SAMR Enum Domain Users. start_idx: %d, acb: %d, size: %d\n",
+			*start_idx, acb_mask, size));
+	
+	/* fill query structure with parameters */
+	init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
+	
+	/* prepare query stream */
+	if (!samr_io_q_enum_dom_users("", &q, &qdata, 0)) {
+		prs_mem_free(&qdata);
+		prs_mem_free(&rdata);
+		return result;
+	};
+	
+	/* send rpc call over the pipe */
+	if (!rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &qdata, &rdata)) {
+		prs_mem_free(&qdata);
+		prs_mem_free(&rdata);
+		return result;
+	}
+		
+	/* unpack received stream */
+	if(!samr_io_r_enum_dom_users("", &r, &rdata, 0)) {
+		prs_mem_free(&qdata);
+		prs_mem_free(&rdata);
+		result = r.status;
+		return result;
+	}
+	
+	/* return the data obtained in response */
+	if (!NT_STATUS_IS_OK(r.status) &&
+		(NT_STATUS_EQUAL(r.status, STATUS_MORE_ENTRIES) ||
+		NT_STATUS_EQUAL(r.status, NT_STATUS_NO_MORE_ENTRIES))) {
+		return r.status;
+	};
+	
+	*start_idx = r.next_idx;
+	*num_dom_users = r.num_entries2;
+	result = r.status;
+
+	/* allocate memory needed to return received data */	
+	*rids = (uint32*)talloc(mem_ctx, sizeof(uint32[r.num_entries2]));
+	if (!*rids) {
+		DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
+		return NT_STATUS_NO_MEMORY;
+	};
+		
+	*dom_users = (char**)talloc(mem_ctx, sizeof(char*) * r.num_entries2);
+	if (!*dom_users) {
+		DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
+		return NT_STATUS_NO_MEMORY;
+	};
+
+	/* fill output buffers with rpc response */
+	for (i = 0; i < r.num_entries2; i++) {
+		fstring conv_buf;
+		
+		(*rids)[i] = r.sam[i].rid;
+		unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1);
+		(*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf);
+	};
+	
+	prs_mem_free(&qdata);
+	prs_mem_free(&rdata);
+	
+	return result;
+};
+
+
 /* Enumerate domain groups */
 
 NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
Index: source/libsmb/cliconnect.c
===================================================================
RCS file: /cvsroot/samba/source/libsmb/cliconnect.c,v
retrieving revision 1.89
diff -u -r1.89 cliconnect.c
--- source/libsmb/cliconnect.c	20 Jul 2002 11:58:05 -0000	1.89
+++ source/libsmb/cliconnect.c	22 Jul 2002 12:28:51 -0000
@@ -1191,9 +1191,8 @@
 	if (!cli_session_setup(cli, user, password, strlen(password)+1, 
 			       password, strlen(password)+1, 
 			       domain)) {
-		if (!(flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) 
-		    || cli_session_setup(cli, "", "", 0, 
-					 "", 0, domain)) {
+		if ((flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK)
+		    && cli_session_setup(cli, "", "", 0, "", 0, domain)) {
 		} else {
 			nt_status = cli_nt_error(cli);
 			DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status)));
Index: source/passdb/pdb_tdb.c
===================================================================
RCS file: /cvsroot/samba/source/passdb/pdb_tdb.c,v
retrieving revision 1.67
diff -u -r1.67 pdb_tdb.c
--- source/passdb/pdb_tdb.c	21 Jul 2002 04:55:11 -0000	1.67
+++ source/passdb/pdb_tdb.c	22 Jul 2002 12:29:00 -0000
@@ -542,7 +542,7 @@
 		/* increment to next in line */
 		tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
 
-	/* do we have an valid interation pointer? */
+	/* do we have an valid iteration pointer? */
 	if(tdb_state->passwd_tdb == NULL) {
 		DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
 		return False;
Index: source/passdb/secrets.c
===================================================================
RCS file: /cvsroot/samba/source/passdb/secrets.c,v
retrieving revision 1.38
diff -u -r1.38 secrets.c
--- source/passdb/secrets.c	20 Jul 2002 13:02:46 -0000	1.38
+++ source/passdb/secrets.c	22 Jul 2002 12:29:01 -0000
@@ -388,7 +388,9 @@
 
 
 /**
- * The linked list is allocated on the supplied talloc context, caller gets to destory
+ * Get trusted domains info from secrets.tdb.
+ *
+ * The linked list is allocated on the supplied talloc context, caller gets to destroy
  * when done.
  *
  * @param ctx Allocation context
@@ -409,10 +411,11 @@
 	int start_idx;
 	uint32 idx = 0;
 	size_t size;
+	char dom_name[32];
 	struct trusted_dom_pass *pass;
 	NTSTATUS status;
 
-	secrets_init();
+	if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
 
 	*num_domains = 0;
 	start_idx = *enum_ctx;
@@ -455,6 +458,10 @@
 			SAFE_FREE(pass);
 			continue;
 		}
+		
+		ucs2_to_ascii(dom_name, pass->uni_name, sizeof(dom_name));
+		DEBUG(18, ("Fetched secret record num %d.\nDomain name: %s, SID: %s\n",
+			   idx, dom_name, sid_string_static(&pass->domain_sid)));
 
 		SAFE_FREE(secrets_key);
 
@@ -475,6 +482,10 @@
 			dom->name = talloc_strdup_w(ctx, pass->uni_name);
 			
 			(*domains)[idx - start_idx] = dom;
+			
+			DEBUG(18, ("Secret record is in required range.\n
+				   start_idx = %d, max_num_domains = %d. Added to returned array.\n",
+				   start_idx, max_num_domains));
 
 			*enum_ctx = idx + 1;
 			(*num_domains)++;
@@ -487,6 +498,10 @@
 				/* this is the last entry in the whole enumeration */
 				status = NT_STATUS_OK;
 			}
+		} else {
+			DEBUG(18, ("Secret is outside the required range.\n
+				   start_idx = %d, max_num_domains = %d. Not added to returned array\n",
+				   start_idx, max_num_domains));
 		}
 		
 		idx++;
Index: source/smbd/process.c
===================================================================
RCS file: /cvsroot/samba/source/smbd/process.c,v
retrieving revision 1.99
diff -u -r1.99 process.c
--- source/smbd/process.c	20 Jul 2002 08:44:34 -0000	1.99
+++ source/smbd/process.c	22 Jul 2002 12:29:06 -0000
@@ -152,7 +152,7 @@
   Returns False on timeout or error.
   Else returns True.
 
-The timeout is in milli seconds
+The timeout is in milliseconds
 ****************************************************************************/
 
 static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
Index: source/utils/net_rpc.c
===================================================================
RCS file: /cvsroot/samba/source/utils/net_rpc.c,v
retrieving revision 1.24
diff -u -r1.24 net_rpc.c
--- source/utils/net_rpc.c	20 Jul 2002 11:58:06 -0000	1.24
+++ source/utils/net_rpc.c	22 Jul 2002 12:29:10 -0000
@@ -1227,7 +1227,7 @@
 
 	/* if argc > 0, must be user command */
 	if (argc > 0)
-		username = argv[0];
+		username = smb_xstrdup(argv[0]);
 		
 	result = cli_srvsvc_net_file_enum(
 		cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd);
@@ -1562,9 +1562,10 @@
 
 extern char *opt_user_name;
 extern char *opt_password;
+extern char *opt_workgroup;
 
-static int rpc_trustdom_establish(int argc, const char **argv) {
-
+static int rpc_trustdom_establish(int argc, const char **argv)
+{
 	struct cli_state *cli;
 	struct in_addr server_ip;
 	POLICY_HND connect_hnd;
@@ -1582,14 +1583,22 @@
 	 */
 
 	if (argc != 1) {
-		d_printf("Usage: net rpc trustdom add <domain_name>\n");
+		d_printf("Usage: net rpc trustdom establish <domain_name>\n");
 		return -1;
 	}
 
-
 	domain_name = smb_xstrdup(argv[0]);
 	strupper(domain_name);
 	
+	/*
+	 * opt_workgroup will be used by connection functions further,
+	 * hence it should be set to remote domain name instead of ours
+	 */
+	if (opt_workgroup) {
+		SAFE_FREE(opt_workgroup);
+		opt_workgroup = smb_xstrdup(domain_name);
+	};
+	
 	asprintf(&acct_name, "%s$", lp_workgroup());
 	strupper(acct_name);
 	
@@ -1679,6 +1688,8 @@
 
 	if (!cli_nt_session_open(cli, PIPE_LSARPC)) {
 		DEBUG(0, ("Could not initialise lsa pipe\n"));
+		cli_shutdown(cli);
+		return -1;
 	}
 
 	nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
@@ -1743,8 +1754,8 @@
  * @return Integer status (0 means success)
  **/
 
-static int rpc_trustdom_revoke(int argc, const char **argv) {
-
+static int rpc_trustdom_revoke(int argc, const char **argv)
+{
 	char* domain_name;
 
 	if (argc < 1) return -1;
@@ -1772,7 +1783,8 @@
  * @return Integer status returned to shell
  **/
  
-static int rpc_trustdom_usage(int argc, const char **argv) {
+static int rpc_trustdom_usage(int argc, const char **argv)
+{
 	d_printf("  net rpc trustdom add \t\t add trusting domain's account\n");
 	d_printf("  net rpc trustdom del \t\t delete trusting domain's account\n");
 	d_printf("  net rpc trustdom establish \t establish relationship to trusted domain\n");
@@ -1782,6 +1794,270 @@
 }
 
 
+extern char* opt_workgroup;
+extern char* opt_host;
+extern char* opt_password;
+
+static int rpc_trustdom_list(int argc, const char **argv)
+{
+	/* common variables */
+	TALLOC_CTX* mem_ctx;
+	struct cli_state *cli_lsa, *cli_samr;
+	NTSTATUS nt_status;
+	struct in_addr server_ip;
+	char *domain_name = NULL;
+	DOM_SID queried_dom_sid;
+	fstring ascii_sid, padding;
+	int ascii_dom_name_len;
+	POLICY_HND connect_hnd;
+	
+	/* trusted domains listing variables */
+	int enum_ctx = 0, pref_num_domains = 5;
+	int num_domains, i, pad_len, col_len = 20;
+	DOM_SID *domain_sids;
+	char **trusted_dom_names;
+	fstring pdc_name;
+	
+	/* trusting domains listing variables */
+	POLICY_HND domain_hnd, remote_dom_hnd;
+	DOM_SID domain_sid;
+	char **trusting_dom_names;
+	uint32 *trusting_dom_rids;
+	
+	/*
+	 * Listing trusted domains (stored in secrets.tdb, if local)
+	 */
+
+	mem_ctx = talloc_init_named("trust relatioships listing");
+
+	/*
+	 * set domain and pdc name to local samba server (default)
+	 * or any other remote one
+	 */
+	strupper(opt_workgroup);
+	if (strcmp(opt_workgroup, lp_workgroup())) {
+		domain_name = smb_xstrdup(opt_workgroup);
+	} else {
+		safe_strcpy(pdc_name, global_myname, FSTRING_LEN);
+		domain_name = smb_xstrdup(lp_workgroup());
+	};
+
+	/* anonymous access is denied */
+	if (!opt_password) {
+		char *pass = getpass("Password:");
+		if (pass) opt_password = strdup(pass);
+	};
+
+	/* find domain controller */
+	if (!net_find_dc(&server_ip, pdc_name, domain_name)) {
+		DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
+		return -1;
+	};
+
+	/*
+	 * Open \PIPE\lsarpc and get policy handle
+	 */		
+	nt_status = connect_to_ipc(&cli_lsa, &server_ip, pdc_name);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		DEBUG(0, ("Couldn't connect to IPC$ of server %s\n", pdc_name));
+		return -1;
+	};
+
+	if (!cli_nt_session_open(cli_lsa, PIPE_LSARPC)) {
+		DEBUG(0, ("Could not initialise lsa pipe\n"));
+		return -1;
+	};
+
+	nt_status = cli_lsa_open_policy2(cli_lsa, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
+					&connect_hnd);
+	if (NT_STATUS_IS_ERR(nt_status)) {
+		DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
+ 			nt_errstr(nt_status)));
+		return -1;
+	};
+	
+	/* Query info level 5 mainly to obtain sid of a domain being queried */
+	nt_status = cli_lsa_query_info_policy(cli_lsa, mem_ctx, &connect_hnd,
+					5 /* info level */, domain_name, &queried_dom_sid);
+	if (NT_STATUS_IS_ERR(nt_status)) {
+		DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
+			nt_errstr(nt_status)));
+		return -1;
+	}
+
+		
+	/*
+	 * Keep calling LsaEnumTrustdom over opened pipe until
+	 * the end of enumeration is reached
+	 */
+	 
+	d_printf("Trusted domains list:\n\n");
+
+	do {
+		nt_status = cli_lsa_enum_trust_dom(cli_lsa, mem_ctx, &connect_hnd, &enum_ctx,
+		                                   &pref_num_domains, &num_domains,
+		                                   &trusted_dom_names, &domain_sids);
+		
+		if (NT_STATUS_IS_ERR(nt_status)) {
+			DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
+				nt_errstr(nt_status)));
+			return -1;
+		};
+		
+		for (i = 0; i < num_domains; i++) {
+			/* convert sid into ascii string */
+			sid_to_string(ascii_sid, &(domain_sids[i]));
+		
+			/* calculate padding space for d_printf to look nicer */
+			pad_len = col_len - strlen(trusted_dom_names[i]);
+			padding[pad_len] = 0;
+			do padding[--pad_len] = ' '; while (pad_len);
+			
+			d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid);
+		};
+
+	} while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
+
+	/* close this connection before doing next one */
+	nt_status = cli_lsa_close(cli_lsa, mem_ctx, &connect_hnd);
+	if (NT_STATUS_IS_ERR(nt_status)) {
+		DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
+			nt_errstr(nt_status)));
+		return -1;
+	};
+
+	cli_shutdown(cli_lsa);
+
+	/*
+	 * Listing trusting domains (stored in passdb backend, if local)
+	 */
+	
+	d_printf("\nTrusting domains list:\n\n");
+
+	/*
+	 * Open \PIPE\samr and get needed policy handles
+	 */		
+	nt_status = connect_to_ipc(&cli_samr, &server_ip, pdc_name);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		DEBUG(0, ("Couldn't connect to IPC$ of server %s\n", pdc_name));
+		return -1;
+	};
+
+	if (!cli_nt_session_open(cli_samr, PIPE_SAMR)) {
+		DEBUG(0, ("Could not initialise samr pipe\n"));
+		return -1;
+	};
+	
+	/* SamrConnect */
+	nt_status = cli_samr_connect(cli_samr, mem_ctx, SAMR_ACCESS_OPEN_DOMAIN,
+								 &connect_hnd);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
+			nt_errstr(nt_status)));
+		return -1;
+	};
+	
+	/* SamrOpenDomain - we have to open domain policy handle in order to be
+	   able to enumerate accounts*/
+	nt_status = cli_samr_open_domain(cli_samr, mem_ctx, &connect_hnd,
+									 DOMAIN_ACCESS_ENUM_ACCOUNTS,
+									 &queried_dom_sid, &domain_hnd);									 
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		DEBUG(0, ("Couldn't open domain object. Error was %s\n",
+			nt_errstr(nt_status)));
+		return -1;
+	};
+	
+	/*
+	 * perform actual enumeration
+	 */
+	 
+	enum_ctx = 0;	/* reset enumeration context from last enumeration */
+	do {
+			
+		nt_status = cli_samr_enum_dom_users(cli_samr, mem_ctx, &domain_hnd,
+		                                    &enum_ctx, ACB_DOMTRUST, 0xffff,
+		                                    &trusting_dom_names, &trusting_dom_rids,
+		                                    &num_domains);
+		if (NT_STATUS_IS_ERR(nt_status)) {
+			DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
+				nt_errstr(nt_status)));
+			return -1;
+		};
+		
+		for (i = 0; i < num_domains; i++) {
+
+			/*
+			 * get every single domain's sid (do we _really_ need this ?):
+			 *  1) find a domain's pdc
+			 *  2) query the pdc for domain's sid
+			 */
+
+			/* get rid of '$' tail */
+			ascii_dom_name_len = strlen(trusting_dom_names[i]);
+			if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
+				trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
+			
+			/* calculate padding space for d_printf to look nicer */
+			pad_len = col_len - strlen(trusting_dom_names[i]);
+			padding[pad_len] = 0;
+			do padding[--pad_len] = ' '; while (pad_len);
+			
+			/* find a domain controller */			
+			if (net_find_dc(&server_ip, pdc_name, trusting_dom_names[i])) {
+			
+				nt_status = connect_to_ipc_anonymous(&cli_lsa, &server_ip, (char*)pdc_name);
+				if (NT_STATUS_IS_OK(nt_status))
+				
+					/* in case of failure in LsaQueryInfoPolicy prevent from converting
+					   garbage to sid string */
+					nt_status = NT_STATUS_UNSUCCESSFUL;
+				
+					/* query for domain's sid */
+					if (cli_nt_session_open(cli_lsa, PIPE_LSARPC)) {
+						nt_status = cli_lsa_open_policy2(cli_lsa, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
+						                                 &remote_dom_hnd);
+						if (NT_STATUS_IS_OK(nt_status)) {
+							nt_status = cli_lsa_query_info_policy(cli_lsa, mem_ctx, &remote_dom_hnd,
+							                                      5 /* info level */, trusting_dom_names[i], &domain_sid);
+							nt_status = cli_lsa_close(cli_lsa, mem_ctx, &remote_dom_hnd);
+							
+							cli_shutdown(cli_lsa);
+						};
+					};
+				
+				if (NT_STATUS_IS_OK(nt_status)) {
+					sid_to_string(ascii_sid, &domain_sid);
+					d_printf("%s%s%s\n", trusting_dom_names[i], padding, ascii_sid);
+				} else {
+					d_printf("%s%scouldn't get domain's sid\n", trusting_dom_names[i], padding);
+				};
+				
+			} else {
+				d_printf("%s%sdomain controller is not responding\n", trusting_dom_names[i], padding);
+			};
+		};
+		
+	} while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
+
+	/* close opened samr and domain policy handles */
+	nt_status = cli_samr_close(cli_samr, mem_ctx, &domain_hnd);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
+	};
+	
+	nt_status = cli_samr_close(cli_samr, mem_ctx, &connect_hnd);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
+	};
+
+	/* close connection to IPC$ */
+	cli_shutdown(cli_samr);
+
+	talloc_destroy(mem_ctx);	 
+	return 0;
+}
+
 /**
  * Entrypoint for 'net rpc trustdom' code
  *
@@ -1799,6 +2074,7 @@
 		{"establish", rpc_trustdom_establish},
 		{"revoke", rpc_trustdom_revoke},
 		{"help", rpc_trustdom_usage},
+		{"list", rpc_trustdom_list},
 		{NULL, NULL}
 	};
 
Index: source/utils/smbpasswd.c
===================================================================
RCS file: /cvsroot/samba/source/utils/smbpasswd.c,v
retrieving revision 1.143
diff -u -r1.143 smbpasswd.c
--- source/utils/smbpasswd.c	22 May 2002 12:44:45 -0000	1.143
+++ source/utils/smbpasswd.c	22 Jul 2002 12:29:11 -0000
@@ -92,7 +92,7 @@
 
 	user_name[0] = '\0';
 
-	while ((ch = getopt(argc, argv, "c:axdehmnjr:sw:R:D:U:L")) != EOF) {
+	while ((ch = getopt(argc, argv, "c:axdehminjr:sw:R:D:U:L")) != EOF) {
 		switch(ch) {
 		case 'L':
 			local_flags |= LOCAL_AM_ROOT;
@@ -416,9 +416,11 @@
 				exit(1);
 			}
 		}
+		
+		/* prepare '$' terminated username */
 		slprintf(buf, sizeof(buf) - 1, "%s$", user_name);
 		fstrcpy(user_name, buf);
-
+		
 	} else {
 		
 		if (remote_machine != NULL) {


More information about the samba-technical mailing list