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@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; }