smbpasswd not handling password server = * correctly

ZINKEVICIUS,MATT (HP-Loveland,ex1) matt_zinkevicius at hp.com
Wed Feb 20 18:28:04 GMT 2002


Hi Alan,
Here I reported this problem along with 2 others in smbpasswd about a month
ago. Here's the patch I came up with (against 2.2.3a):

smbpasswd-dcdetect.patch
------------------------
  - Fixes bug where joining a domain with a given username
    and password would not read the password server line
    out of smb.conf.
  - Fixes bug where joining a domain with a given username
    and password would not correctly handle "*" as the
    remote machine (which should use the autodetected PDC).
  - Fixes bug where joining a domain with an existing account
    would not correctly handle "*" as the the remote machine.
    (it would use the lp_workgroup() field instead of the
    domain that was passed to determine the PDC).
  - Add a "-c" option to print the autodetected domain controller
    for the given domain.


--- samba-2.2-orig/source/utils/smbpasswd.c	Sun Feb  3 00:46:57 2002
+++ samba-2.2-dcdetect/source/utils/smbpasswd.c	Wed Feb  6 09:49:00 2002
@@ -69,6 +69,7 @@
 		printf("  -L                   local mode (must be first
option)\n");
 		printf("  -R ORDER             name resolve order\n");
 		printf("  -j DOMAIN            join domain name\n");
+		printf("  -c DOMAIN            print domain controller for
DOMAIN\n");
 		printf("  -a                   add user\n");
 		printf("  -x                   delete user\n");
 		printf("  -d                   disable user\n");
@@ -99,6 +100,18 @@
 	fstrcpy(creds->domain, domain);
 }
 
+/* Return the name of the autodetected domain controller */
+BOOL get_dc_name(char *domain, char *dc_name)
+{
+	BOOL ret;
+	struct in_addr domain_ip;
+
+	ret = resolve_name(domain, &domain_ip, 0x1B);
+	lookup_dc_name(global_myname, domain, &domain_ip, dc_name);
+
+	return ret;
+}
+
 /*********************************************************
 Join a domain using the administrator username and password
 **********************************************************/
@@ -117,7 +130,7 @@
                 goto done; \
         }
 
-static int join_domain_byuser(char *domain, char *remote_machine,
+static int join_domain_byuser(char *domain, char *remote,
 			      char *username, char *password)
 {
 	/* libsmb variables */
@@ -148,6 +161,8 @@
 
 	NTSTATUS result;
 	int retval = 1;
+	pstring remote_machine;
+	pstrcpy(remote_machine, remote ? remote : "");
 
 	/* Connect to remote machine */
 
@@ -167,6 +182,19 @@
 	init_rpcclient_creds(&creds, username, domain, password);
 	cli_init_creds(&cli, &creds);
 
+	/* If we are given a remote machine assume this is the PDC */
+	if(remote == NULL) {
+		pstrcpy(remote_machine, lp_passwordserver());
+	}
+
+	/* Replace "*" with the detected domain controller */
+	if (strcmp(remote_machine, "*") == 0) {
+		if (!get_dc_name(domain, remote_machine)) {
+			DEBUG(0, ("Could not determine domain controller's
name\n"));
+			goto done;
+		}
+	}
+
 	if (!resolve_srv_name(remote_machine, dest_host, &dest_ip)) {
 		DEBUG(0, ("Could not resolve name %s\n", remote_machine));
 		goto done;
@@ -419,6 +447,14 @@
 		pstrcpy(remote_machine, lp_passwordserver());
 	}
 
+	/* Replace "*" with the detected domain controller */
+	if (strcmp(remote_machine, "*") == 0) {
+		if (!get_dc_name(domain, remote_machine)) {
+			fprintf(stderr,"Could not determine domain
controller's name\n");
+			return 1;
+		}
+	}
+
 	if(!*remote_machine) {
 		fprintf(stderr, "No password server list given in smb.conf -
\
 unable to join domain.\n");
@@ -579,6 +615,7 @@
 	struct passwd  *pwd;
 	int result = 0, ch;
 	BOOL joining_domain = False, got_pass = False, got_username = False;
+	BOOL print_dc = False;
 	int local_flags = 0;
 	BOOL stdin_passwd_get = False;
 	fstring user_name, user_password;
@@ -592,7 +629,7 @@
 
 	user_name[0] = '\0';
 
-	while ((ch = getopt(argc, argv, "axdehmnj:r:sw:R:D:U:L")) != EOF) {
+	while ((ch = getopt(argc, argv, "axdehmnj:c:r:sw:R:D:U:L")) != EOF)
{
 		switch(ch) {
 		case 'L':
 			local_mode = True;
@@ -623,6 +660,11 @@
 			strupper(new_domain);
 			joining_domain = True;
 			break;
+		case 'c':
+			new_domain = optarg;
+			strupper(new_domain);
+			print_dc = True;
+			break;
 		case 'r':
 			remote_machine = optarg;
 			break;
@@ -729,6 +771,20 @@
 
 			return join_domain(new_domain, remote_machine);
 		}
+	}
+
+	/* Print domain controller's name */
+
+	if (print_dc) {
+		
+		pstring dc_name;
+		
+		if (get_dc_name(new_domain, dc_name)) {
+			printf("%s\n", dc_name);
+			return 0;
+		}
+		
+		return 1;
 	}
 
 	/*




> -----Original Message-----
> From: Romeril, Alan [mailto:a.romeril at ic.ac.uk]
> Sent: Wednesday, February 20, 2002 7:03 PM
> To: Samba-Technical (E-mail)
> Subject: smbpasswd not handling password server = * correctly
> 
> 
> Hello Everyone,
> 	We ran into a tricky problem earlier on today with 
> attempting to join a
> domain with password server = * set.
> It seems that fetch_domain_sid in libsmb/cli_lsarpc.c does not expand
> the wildcard * passed to it as remote_machine into the server list.
> This ends up with name lookups for *#20 getting sent across the wire. 
> This caused a bit of a problem as only the Samba boxes on the subnet
> respond to that, and the fastest responder of those gave the wrong
> answer.  So machines attempted to join a non-existent domain (the
> netbios name of the fastest responder) and failed.
> 	This is very different behaviour to say the late 2.0.x 
> smbpasswd that
> correctly hunts for domain controllers, could one of the team take a
> look at this bug?
> 
> Cheers,
> Alan
> 
> p.s
> I just knocked up a quick change to smbpasswd as a test (and to get us
> out of the hole) and this joins the domain quite happily but of course
> is not the solution that is really needed.
> (Excuse any mangling that Netscape does on this...)
> 
> --- smbpasswd.c Thu Feb 21 01:32:16 2002
> +++ smbpasswd.c Thu Feb 21 01:31:34 2002
> @@ -386,7 +386,8 @@
>         unsigned char orig_trust_passwd_hash[16];
>         DOM_SID domain_sid;
>         BOOL ret;
> -
> +       struct in_addr *ip;
> +
>         pstrcpy(remote_machine, remote ? remote : "");
>         fstrcpy(trust_passwd, global_myname);
>         strlower(trust_passwd);
> @@ -423,6 +424,12 @@
>                 fprintf(stderr, "No password server list given in
> smb.conf - \
>  unable to join domain.\n");
>                 return 1;
> +       }
> +
> +       if(*remote_machine == '*') {
> +       DEBUG(10, ("Wildcard password server given.  Finding PDC\n"));
> +       ret = resolve_name(lp_workgroup(), ip, 0x1B); 
> +       lookup_dc_name(global_myname, lp_workgroup(), ip,
> remote_machine);
>         }
>  
>         if (!fetch_domain_sid( domain, remote_machine, &domain_sid) ||
> 




More information about the samba-technical mailing list