[Samba] join domain without root

Paul Szabo psz at maths.usyd.edu.au
Mon Mar 15 21:55:03 GMT 2004


Dear Samba gurus,

I am still using Samba 2.2.8a; I have not seen an announcement that this
issue would be fixed in 3.0.2; all that follows refers to 2.2.8a.

Quoting from Samba-PDC-HOWTO.html (or Samba-HOWTO-Collection.html):

  Joining the Client to the Domain
     Windows 2000
     ... Windows prompts for an account and password that is privileged to
     join the domain. A Samba administrative account (i.e., a Samba account
     that has root privileges on the Samba server) must be entered here ...

This seems an onerous imposition, as it involves a security risk. In my
environment (Samba PDC with W2k clients) the following patch solves the
issue, allowing any account marked "domain admin" in smb.conf to be used.

Cheers,

Paul Szabo - psz at maths.usyd.edu.au  http://www.maths.usyd.edu.au:8000/u/psz/
School of Mathematics and Statistics  University of Sydney   2006  Australia


--- rpc_server/srv_samr_nt.c.old	Sat Mar 15 08:34:49 2003
+++ rpc_server/srv_samr_nt.c	Tue Mar 16 06:14:29 2004
@@ -2369,16 +2369,67 @@
 	uint32 len;
 	pstring buf;
 	uint16 acct_ctrl;
+	int do_become_root;
+	BOOL ret;
  
  	pdb_init_sam(&pwd);
  
-	if (!pdb_getsampwrid(pwd, rid)) {
+/* PSz 15 Mar 04
+ * This code is called, as the "domain admin", when a machine is joining
+ * the domain, both with netdom and via sysprep/mini-setup.
+ * Do as root (bracket within become_root()/unbecome_root() if it is
+ * a domain admin, updating his own machine password. (Otherwise the
+ * pdb_ calls fail for non-root.)
+ * More precisely: bracket pdb_getsampwrid if I am a domain admin; then
+ * also bracket pdb_update_sam_account if rid is my own machine account.
+ */
+	do_become_root = 0;
+	if (geteuid()) {
+	    struct passwd* pass;
+	    /* Should we use current_user->uid, or current_user->conn->uid
+	     * and current_user->conn->user, for any of this? */
+	    if ( (pass=sys_getpwuid(geteuid())) != NULL ) {
+		if ( user_in_list(pass->pw_name, lp_domain_admin_group()) ) {
+			do_become_root = 1;
+			DEBUG(1, ("set_user_info_pw: EUID %d for rid=%d(=0x%x), with become_root\n", geteuid(), rid, rid));
+		}
+	    }
+	}
+
+	if (do_become_root) become_root();
+	ret = pdb_getsampwrid(pwd, rid);
+	if (do_become_root) unbecome_root();
+	if (ret != True) {
 		pdb_free_sam(pwd);
 		return False;
  	}
 	
 	acct_ctrl = pdb_get_acct_ctrl(pwd);
 
+	if (do_become_root) {
+		char *username, *hostname, *s;
+		username = pdb_get_username(pwd);
+		DEBUG(0, ("set_user_info_pw: EUID %d for %s, with become_root\n", geteuid(), username));
+		if ( !(acct_ctrl & ACB_WSTRUST) ) {
+			DEBUG(0, ("set_user_info_pw: Not a machine account\n"));
+			pdb_free_sam(pwd);
+			return False;
+		}
+		hostname = client_name();
+		/* Not simply len = strlen(hostname): stop at first dot */
+		for (s = hostname, len = 0; *s && *s != '.'; s++, len++);
+		if (! (
+		    len > 0 &&
+		    len + 1 == strlen(username) &&
+		    username[len] == '$' &&
+		    strncmp(hostname,username,len) == 0
+		    ) ) {
+			DEBUG(0, ("set_user_info_pw: Wrong account %s for host %s\n", username, hostname));
+			pdb_free_sam(pwd);
+			return False;
+		}
+	}
+
 	memset(buf, 0, sizeof(buf));
  
 	if (!decode_pw_buffer(pass, buf, 256, &len, nt_hash, lm_hash)) {
@@ -2414,7 +2465,10 @@
 	DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
  
 	/* update the SAMBA password */
-	if(!pdb_update_sam_account(pwd, True)) {
+	if (do_become_root) become_root();
+	ret = pdb_update_sam_account(pwd, True);
+	if (do_become_root) unbecome_root();
+	if (ret != True) {
 		pdb_free_sam(pwd);
 		return False;
  	}


More information about the samba mailing list