xref: /titanic_52/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c (revision b3700b074e637f8c6991b70754c88a2cfffb246b)
1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
20da6c28aaSamw  */
21da6c28aaSamw /*
221fdeec65Sjoyce mcintosh  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23*b3700b07SGordon Ross  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
24da6c28aaSamw  */
25da6c28aaSamw 
26da6c28aaSamw /*
27da6c28aaSamw  * Utility functions to support the RPC interface library.
28da6c28aaSamw  */
29da6c28aaSamw 
30da6c28aaSamw #include <stdio.h>
31da6c28aaSamw #include <stdarg.h>
32da6c28aaSamw #include <strings.h>
33da6c28aaSamw #include <unistd.h>
34da6c28aaSamw #include <netdb.h>
35da6c28aaSamw #include <stdlib.h>
36da6c28aaSamw #include <sys/time.h>
37da6c28aaSamw #include <sys/systm.h>
38b819cea2SGordon Ross #include <note.h>
39fc724630SAlan Wright #include <syslog.h>
40da6c28aaSamw 
41da6c28aaSamw #include <smbsrv/libsmb.h>
42da6c28aaSamw #include <smbsrv/libsmbns.h>
43da6c28aaSamw #include <smbsrv/libmlsvc.h>
441ed6b69aSGordon Ross #include <smbsrv/ntaccess.h>
45da6c28aaSamw #include <smbsrv/smbinfo.h>
46*b3700b07SGordon Ross #include <smbsrv/netrauth.h>
47ed9aabc7SGordon Ross #include <libsmbrdr.h>
488d7e4166Sjose borrego #include <lsalib.h>
498d7e4166Sjose borrego #include <samlib.h>
50*b3700b07SGordon Ross #include <mlsvc.h>
51da6c28aaSamw 
521ed6b69aSGordon Ross static DWORD
531ed6b69aSGordon Ross mlsvc_join_rpc(smb_domainex_t *dxi,
541ed6b69aSGordon Ross 	char *admin_user, char *admin_pw,
551ed6b69aSGordon Ross 	char *machine_name, char *machine_pw);
561ed6b69aSGordon Ross static DWORD
571ed6b69aSGordon Ross mlsvc_join_noauth(smb_domainex_t *dxi,
581ed6b69aSGordon Ross 	char *machine_name, char *machine_pw);
591ed6b69aSGordon Ross 
601ed6b69aSGordon Ross 
61faa1795aSjb150015 DWORD
62faa1795aSjb150015 mlsvc_netlogon(char *server, char *domain)
63faa1795aSjb150015 {
64faa1795aSjb150015 	mlsvc_handle_t netr_handle;
65faa1795aSjb150015 	DWORD status;
66faa1795aSjb150015 
67*b3700b07SGordon Ross 	status = netr_open(server, domain, &netr_handle);
68*b3700b07SGordon Ross 	if (status != 0) {
691ed6b69aSGordon Ross 		syslog(LOG_NOTICE, "Failed to connect to %s "
70*b3700b07SGordon Ross 		    "for domain %s (%s)", server, domain,
71*b3700b07SGordon Ross 		    xlate_nt_status(status));
72*b3700b07SGordon Ross 		return (status);
73faa1795aSjb150015 	}
74faa1795aSjb150015 
75*b3700b07SGordon Ross 	status = netlogon_auth(server, &netr_handle, NETR_FLG_INIT);
76*b3700b07SGordon Ross 	if (status != NT_STATUS_SUCCESS) {
77*b3700b07SGordon Ross 		syslog(LOG_NOTICE, "Failed to establish NETLOGON "
78*b3700b07SGordon Ross 		    "credential chain with DC: %s (%s)", server,
79*b3700b07SGordon Ross 		    xlate_nt_status(status));
80*b3700b07SGordon Ross 		syslog(LOG_NOTICE, "The machine account information on the "
81*b3700b07SGordon Ross 		    "domain controller does not match the local storage.");
82*b3700b07SGordon Ross 		syslog(LOG_NOTICE, "To correct this, use 'smbadm join'");
83*b3700b07SGordon Ross 	}
84*b3700b07SGordon Ross 	(void) netr_close(&netr_handle);
85*b3700b07SGordon Ross 
86faa1795aSjb150015 	return (status);
87faa1795aSjb150015 }
88faa1795aSjb150015 
89da6c28aaSamw /*
901ed6b69aSGordon Ross  * Join the specified domain.  The method varies depending on whether
911ed6b69aSGordon Ross  * we're using "secure join" (using an administrative account to join)
921ed6b69aSGordon Ross  * or "unsecure join" (using a pre-created machine account).  In the
931ed6b69aSGordon Ross  * latter case, the machine account is created "by hand" before this
941ed6b69aSGordon Ross  * machine attempts to join, and we just change the password from the
951ed6b69aSGordon Ross  * (weak) default password for a new machine account to a random one.
96eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  *
97da6c28aaSamw  * Returns NT status codes.
98da6c28aaSamw  */
99*b3700b07SGordon Ross void
100*b3700b07SGordon Ross mlsvc_join(smb_joininfo_t *info, smb_joinres_t *res)
101da6c28aaSamw {
102*b3700b07SGordon Ross 	static unsigned char zero_hash[SMBAUTH_HASH_SZ];
1031ed6b69aSGordon Ross 	char machine_name[SMB_SAMACCT_MAXLEN];
1041ed6b69aSGordon Ross 	char machine_pw[NETR_MACHINE_ACCT_PASSWD_MAX];
1051ed6b69aSGordon Ross 	unsigned char passwd_hash[SMBAUTH_HASH_SZ];
106*b3700b07SGordon Ross 	smb_domainex_t dxi;
107*b3700b07SGordon Ross 	smb_domain_t *di = &dxi.d_primary;
108da6c28aaSamw 	DWORD status;
1091ed6b69aSGordon Ross 	int rc;
110da6c28aaSamw 
111*b3700b07SGordon Ross 	bzero(&dxi, sizeof (dxi));
112*b3700b07SGordon Ross 
1131ed6b69aSGordon Ross 	/*
1141ed6b69aSGordon Ross 	 * Domain join support: AD (Kerberos+LDAP) or MS-RPC?
1151ed6b69aSGordon Ross 	 */
1161ed6b69aSGordon Ross 	boolean_t ads_enabled = smb_config_get_ads_enable();
117da6c28aaSamw 
118*b3700b07SGordon Ross 	if (smb_getsamaccount(machine_name, sizeof (machine_name)) != 0) {
119*b3700b07SGordon Ross 		res->status = NT_STATUS_INVALID_COMPUTER_NAME;
120*b3700b07SGordon Ross 		return;
121*b3700b07SGordon Ross 	}
122da6c28aaSamw 
1231ed6b69aSGordon Ross 	(void) smb_gen_random_passwd(machine_pw, sizeof (machine_pw));
124eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
1251ed6b69aSGordon Ross 	/*
126*b3700b07SGordon Ross 	 * Ensure that any previous membership of this domain has
127*b3700b07SGordon Ross 	 * been cleared from the environment before we start. This
128*b3700b07SGordon Ross 	 * will ensure that we don't attempt a NETLOGON_SAMLOGON
129*b3700b07SGordon Ross 	 * when attempting to find the PDC.
1301ed6b69aSGordon Ross 	 */
131*b3700b07SGordon Ross 	(void) smb_config_setbool(SMB_CI_DOMAIN_MEMB, B_FALSE);
132*b3700b07SGordon Ross 
133*b3700b07SGordon Ross 	if (info->domain_username[0] != '\0') {
134*b3700b07SGordon Ross 		(void) smb_auth_ntlm_hash(info->domain_passwd, passwd_hash);
135*b3700b07SGordon Ross 		smb_ipc_set(info->domain_username, passwd_hash);
136*b3700b07SGordon Ross 	} else {
137*b3700b07SGordon Ross 		smb_ipc_set(MLSVC_ANON_USER, zero_hash);
138*b3700b07SGordon Ross 	}
139da6c28aaSamw 
1401ed6b69aSGordon Ross 	/*
141*b3700b07SGordon Ross 	 * Tentatively set the idmap domain to the one we're joining,
142*b3700b07SGordon Ross 	 * so that the DC locator in idmap knows what to look for.
143*b3700b07SGordon Ross 	 * Ditto the SMB server domain.
144*b3700b07SGordon Ross 	 */
145*b3700b07SGordon Ross 	if (smb_config_set_idmap_domain(info->domain_name) != 0)
146*b3700b07SGordon Ross 		syslog(LOG_NOTICE, "Failed to set idmap domain name");
147*b3700b07SGordon Ross 	if (smb_config_refresh_idmap() != 0)
148*b3700b07SGordon Ross 		syslog(LOG_NOTICE, "Failed to refresh idmap service");
149*b3700b07SGordon Ross 
150*b3700b07SGordon Ross 	/* Clear DNS local (ADS) lookup cache. */
151*b3700b07SGordon Ross 	smb_ads_refresh(B_FALSE);
152*b3700b07SGordon Ross 
153*b3700b07SGordon Ross 	/*
154*b3700b07SGordon Ross 	 * Locate a DC for this domain.  Intentionally bypass the
155*b3700b07SGordon Ross 	 * ddiscover service here because we're still joining.
156*b3700b07SGordon Ross 	 * This also allows better reporting of any failures.
157*b3700b07SGordon Ross 	 */
158*b3700b07SGordon Ross 	status = smb_ads_lookup_msdcs(info->domain_name, &dxi.d_dci);
159*b3700b07SGordon Ross 	if (status != NT_STATUS_SUCCESS) {
160*b3700b07SGordon Ross 		syslog(LOG_ERR,
161*b3700b07SGordon Ross 		    "smbd: failed to locate AD server for domain %s (%s)",
162*b3700b07SGordon Ross 		    info->domain_name, xlate_nt_status(status));
163*b3700b07SGordon Ross 		goto out;
164*b3700b07SGordon Ross 	}
165*b3700b07SGordon Ross 
166*b3700b07SGordon Ross 	/*
167*b3700b07SGordon Ross 	 * Found a DC.  Report what we found along with the return status
168*b3700b07SGordon Ross 	 * so that admin will know which AD server we were talking to.
169*b3700b07SGordon Ross 	 */
170*b3700b07SGordon Ross 	(void) strlcpy(res->dc_name, dxi.d_dci.dc_name, MAXHOSTNAMELEN);
171*b3700b07SGordon Ross 	syslog(LOG_INFO, "smbd: found AD server %s", dxi.d_dci.dc_name);
172*b3700b07SGordon Ross 
173*b3700b07SGordon Ross 	/*
174*b3700b07SGordon Ross 	 * Domain discovery needs to authenticate with the AD server.
175*b3700b07SGordon Ross 	 * Disconnect any existing connection with the domain controller
176*b3700b07SGordon Ross 	 * to make sure we won't use any prior authentication context
177*b3700b07SGordon Ross 	 * our redirector might have.
178*b3700b07SGordon Ross 	 */
179*b3700b07SGordon Ross 	mlsvc_disconnect(dxi.d_dci.dc_name);
180*b3700b07SGordon Ross 
181*b3700b07SGordon Ross 	/*
182*b3700b07SGordon Ross 	 * Get the domain policy info (domain SID etc).
183*b3700b07SGordon Ross 	 * Here too, bypass the smb_ddiscover_service.
184*b3700b07SGordon Ross 	 */
185*b3700b07SGordon Ross 	status = smb_ddiscover_main(info->domain_name, &dxi);
186*b3700b07SGordon Ross 	if (status != NT_STATUS_SUCCESS) {
187*b3700b07SGordon Ross 		syslog(LOG_ERR,
188*b3700b07SGordon Ross 		    "smbd: failed getting domain info for %s (%s)",
189*b3700b07SGordon Ross 		    info->domain_name, xlate_nt_status(status));
190*b3700b07SGordon Ross 		goto out;
191*b3700b07SGordon Ross 	}
192*b3700b07SGordon Ross 	/*
193*b3700b07SGordon Ross 	 * After a successful smbd_ddiscover_main() call
194*b3700b07SGordon Ross 	 * we should call smb_domain_save() to update the
195*b3700b07SGordon Ross 	 * data shown by smbadm list.  Do that at the end,
196*b3700b07SGordon Ross 	 * only if all goes well with joining the domain.
197*b3700b07SGordon Ross 	 */
198*b3700b07SGordon Ross 
199*b3700b07SGordon Ross 	/*
200*b3700b07SGordon Ross 	 * Create or update our machine account on the DC.
201*b3700b07SGordon Ross 	 * A non-null user means we do "secure join".
202*b3700b07SGordon Ross 	 */
203*b3700b07SGordon Ross 	if (info->domain_username[0] != '\0') {
204*b3700b07SGordon Ross 		/*
2051ed6b69aSGordon Ross 		 * If enabled, try to join using AD Services.
2061ed6b69aSGordon Ross 		 */
207da6c28aaSamw 		status = NT_STATUS_UNSUCCESSFUL;
2081ed6b69aSGordon Ross 		if (ads_enabled) {
209*b3700b07SGordon Ross 			res->join_err = smb_ads_join(di->di_fqname,
210*b3700b07SGordon Ross 			    info->domain_username, info->domain_passwd,
211*b3700b07SGordon Ross 			    machine_pw);
212*b3700b07SGordon Ross 			if (res->join_err == SMB_ADS_SUCCESS) {
2131ed6b69aSGordon Ross 				status = NT_STATUS_SUCCESS;
214da6c28aaSamw 			}
215*b3700b07SGordon Ross 		} else {
216*b3700b07SGordon Ross 			syslog(LOG_DEBUG, "use_ads=false (do RPC join)");
217da6c28aaSamw 
2181ed6b69aSGordon Ross 			/*
219*b3700b07SGordon Ross 			 * If ADS was disabled, join using RPC.
2201ed6b69aSGordon Ross 			 */
221*b3700b07SGordon Ross 			status = mlsvc_join_rpc(&dxi,
222*b3700b07SGordon Ross 			    info->domain_username,
223*b3700b07SGordon Ross 			    info->domain_passwd,
2241ed6b69aSGordon Ross 			    machine_name, machine_pw);
2251ed6b69aSGordon Ross 		}
2261ed6b69aSGordon Ross 
2271ed6b69aSGordon Ross 	} else {
2281ed6b69aSGordon Ross 		/*
2291ed6b69aSGordon Ross 		 * Doing "Unsecure join" (pre-created account)
2301ed6b69aSGordon Ross 		 */
231*b3700b07SGordon Ross 		status = mlsvc_join_noauth(&dxi, machine_name, machine_pw);
2321ed6b69aSGordon Ross 	}
2331ed6b69aSGordon Ross 
2341ed6b69aSGordon Ross 	if (status != NT_STATUS_SUCCESS)
2351ed6b69aSGordon Ross 		goto out;
2361ed6b69aSGordon Ross 
2371ed6b69aSGordon Ross 	/*
2381ed6b69aSGordon Ross 	 * Make sure we can authenticate using the
2391ed6b69aSGordon Ross 	 * (new, or updated) machine account.
2401ed6b69aSGordon Ross 	 */
2411ed6b69aSGordon Ross 	(void) smb_auth_ntlm_hash(machine_pw, passwd_hash);
2421ed6b69aSGordon Ross 	smb_ipc_set(machine_name, passwd_hash);
243*b3700b07SGordon Ross 	rc = smbrdr_logon(dxi.d_dci.dc_name, di->di_nbname, machine_name);
2441ed6b69aSGordon Ross 	if (rc != 0) {
2451ed6b69aSGordon Ross 		syslog(LOG_NOTICE, "Authenticate with "
2461ed6b69aSGordon Ross 		    "new/updated machine account: %s",
2471ed6b69aSGordon Ross 		    strerror(rc));
248*b3700b07SGordon Ross 		res->join_err = SMB_ADJOIN_ERR_AUTH_NETLOGON;
2491ed6b69aSGordon Ross 		status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2501ed6b69aSGordon Ross 		goto out;
2511ed6b69aSGordon Ross 	}
2521ed6b69aSGordon Ross 
2531ed6b69aSGordon Ross 	/*
254*b3700b07SGordon Ross 	 * Store the new machine account password, and
255*b3700b07SGordon Ross 	 * SMB_CI_DOMAIN_MEMB etc.
2561ed6b69aSGordon Ross 	 */
257*b3700b07SGordon Ross 	rc = smb_setdomainprops(NULL, dxi.d_dci.dc_name, machine_pw);
2581ed6b69aSGordon Ross 	if (rc != 0) {
2599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_NOTICE,
2601ed6b69aSGordon Ross 		    "Failed to save machine account password");
261*b3700b07SGordon Ross 		res->join_err = SMB_ADJOIN_ERR_STORE_PROPS;
2621ed6b69aSGordon Ross 		status = NT_STATUS_INTERNAL_DB_ERROR;
2631ed6b69aSGordon Ross 		goto out;
264fc724630SAlan Wright 	}
265da6c28aaSamw 
2661ed6b69aSGordon Ross 	/*
267*b3700b07SGordon Ross 	 * Update idmap config?
268*b3700b07SGordon Ross 	 * Already set the domain_name above.
2691ed6b69aSGordon Ross 	 */
2701ed6b69aSGordon Ross 
2711ed6b69aSGordon Ross 	/*
272*b3700b07SGordon Ross 	 * Save the SMB server config.  Sets: SMB_CI_DOMAIN_*
273*b3700b07SGordon Ross 	 * Should unify SMB vs idmap configs.
2741ed6b69aSGordon Ross 	 */
275*b3700b07SGordon Ross 	smb_config_setdomaininfo(di->di_nbname, di->di_fqname,
276*b3700b07SGordon Ross 	    di->di_sid,
277*b3700b07SGordon Ross 	    di->di_u.di_dns.ddi_forest,
278*b3700b07SGordon Ross 	    di->di_u.di_dns.ddi_guid);
279*b3700b07SGordon Ross 	smb_ipc_commit();
280*b3700b07SGordon Ross 	smb_domain_save();
281*b3700b07SGordon Ross 
2821ed6b69aSGordon Ross 	status = 0;
2831ed6b69aSGordon Ross 
2841ed6b69aSGordon Ross out:
285*b3700b07SGordon Ross 
286*b3700b07SGordon Ross 	if (status != 0) {
287*b3700b07SGordon Ross 		/*
288*b3700b07SGordon Ross 		 * Undo the tentative domain settings.
289*b3700b07SGordon Ross 		 */
290*b3700b07SGordon Ross 		(void) smb_config_set_idmap_domain("");
291*b3700b07SGordon Ross 		(void) smb_config_refresh_idmap();
292*b3700b07SGordon Ross 		smb_ipc_rollback();
293*b3700b07SGordon Ross 	}
294*b3700b07SGordon Ross 
2951ed6b69aSGordon Ross 	/* Avoid leaving cleartext passwords around. */
2961ed6b69aSGordon Ross 	bzero(machine_pw, sizeof (machine_pw));
2971ed6b69aSGordon Ross 	bzero(passwd_hash, sizeof (passwd_hash));
2981ed6b69aSGordon Ross 
299*b3700b07SGordon Ross 	res->status = status;
300da6c28aaSamw }
301da6c28aaSamw 
3021ed6b69aSGordon Ross static DWORD
3031ed6b69aSGordon Ross mlsvc_join_rpc(smb_domainex_t *dxi,
3041ed6b69aSGordon Ross 	char *admin_user, char *admin_pw,
3051ed6b69aSGordon Ross 	char *machine_name,  char *machine_pw)
3061ed6b69aSGordon Ross {
3071ed6b69aSGordon Ross 	mlsvc_handle_t samr_handle;
3081ed6b69aSGordon Ross 	mlsvc_handle_t domain_handle;
3091ed6b69aSGordon Ross 	mlsvc_handle_t user_handle;
3101ed6b69aSGordon Ross 	smb_account_t ainfo;
311*b3700b07SGordon Ross 	char *server = dxi->d_dci.dc_name;
3121ed6b69aSGordon Ross 	smb_domain_t *di = &dxi->d_primary;
3131ed6b69aSGordon Ross 	DWORD account_flags;
3141ed6b69aSGordon Ross 	DWORD rid;
3151ed6b69aSGordon Ross 	DWORD status;
3161ed6b69aSGordon Ross 	int rc;
3171ed6b69aSGordon Ross 
3181ed6b69aSGordon Ross 	/* Caller did smb_ipc_set() so we don't need the pw for now. */
3191ed6b69aSGordon Ross 	_NOTE(ARGUNUSED(admin_pw));
3201ed6b69aSGordon Ross 
3211ed6b69aSGordon Ross 	rc = samr_open(server, di->di_nbname, admin_user,
3221ed6b69aSGordon Ross 	    MAXIMUM_ALLOWED, &samr_handle);
3231ed6b69aSGordon Ross 	if (rc != 0) {
3241ed6b69aSGordon Ross 		syslog(LOG_NOTICE, "sam_connect to server %s failed", server);
3251ed6b69aSGordon Ross 		return (RPC_NT_SERVER_UNAVAILABLE);
3261ed6b69aSGordon Ross 	}
3271ed6b69aSGordon Ross 	/* have samr_handle */
3281ed6b69aSGordon Ross 
3291ed6b69aSGordon Ross 	status = samr_open_domain(&samr_handle, MAXIMUM_ALLOWED,
3301ed6b69aSGordon Ross 	    (struct samr_sid *)di->di_binsid, &domain_handle);
3311ed6b69aSGordon Ross 	if (status != NT_STATUS_SUCCESS)
3321ed6b69aSGordon Ross 		goto out_samr_handle;
3331ed6b69aSGordon Ross 	/* have domain_handle */
3341ed6b69aSGordon Ross 
3351ed6b69aSGordon Ross 	account_flags = SAMR_AF_WORKSTATION_TRUST_ACCOUNT;
3361ed6b69aSGordon Ross 	status = samr_create_user(&domain_handle, machine_name,
3371ed6b69aSGordon Ross 	    account_flags, &rid, &user_handle);
3381ed6b69aSGordon Ross 	if (status == NT_STATUS_USER_EXISTS) {
3391ed6b69aSGordon Ross 		status = samr_lookup_domain_names(&domain_handle,
3401ed6b69aSGordon Ross 		    machine_name, &ainfo);
3411ed6b69aSGordon Ross 		if (status != NT_STATUS_SUCCESS)
3421ed6b69aSGordon Ross 			goto out_domain_handle;
3431ed6b69aSGordon Ross 		status = samr_open_user(&domain_handle, MAXIMUM_ALLOWED,
3441ed6b69aSGordon Ross 		    ainfo.a_rid, &user_handle);
3451ed6b69aSGordon Ross 	}
3461ed6b69aSGordon Ross 	if (status != NT_STATUS_SUCCESS) {
3471ed6b69aSGordon Ross 		syslog(LOG_NOTICE,
348*b3700b07SGordon Ross 		    "smbd: failed to open machine account (%s)",
3491ed6b69aSGordon Ross 		    xlate_nt_status(status));
3501ed6b69aSGordon Ross 		goto out_domain_handle;
3511ed6b69aSGordon Ross 	}
3521ed6b69aSGordon Ross 
3531ed6b69aSGordon Ross 	/*
3541ed6b69aSGordon Ross 	 * The account exists, and we have user_handle open
3551ed6b69aSGordon Ross 	 * on that account.  Set the password and flags.
3561ed6b69aSGordon Ross 	 */
3571ed6b69aSGordon Ross 
3581ed6b69aSGordon Ross 	status = netr_set_user_password(&user_handle, machine_pw);
3591ed6b69aSGordon Ross 	if (status != NT_STATUS_SUCCESS) {
3601ed6b69aSGordon Ross 		syslog(LOG_NOTICE,
361*b3700b07SGordon Ross 		    "smbd: failed to set machine account password (%s)",
3621ed6b69aSGordon Ross 		    xlate_nt_status(status));
3631ed6b69aSGordon Ross 		goto out_user_handle;
3641ed6b69aSGordon Ross 	}
3651ed6b69aSGordon Ross 
3661ed6b69aSGordon Ross 	account_flags |= SAMR_AF_DONT_EXPIRE_PASSWD;
3671ed6b69aSGordon Ross 	status = netr_set_user_control(&user_handle, account_flags);
3681ed6b69aSGordon Ross 	if (status != NT_STATUS_SUCCESS) {
3691ed6b69aSGordon Ross 		syslog(LOG_NOTICE,
3701ed6b69aSGordon Ross 		    "Set machine account control flags: %s",
3711ed6b69aSGordon Ross 		    xlate_nt_status(status));
3721ed6b69aSGordon Ross 		goto out_user_handle;
3731ed6b69aSGordon Ross 	}
3741ed6b69aSGordon Ross 
3751ed6b69aSGordon Ross out_user_handle:
3761ed6b69aSGordon Ross 	(void) samr_close_handle(&user_handle);
3771ed6b69aSGordon Ross out_domain_handle:
3781ed6b69aSGordon Ross 	(void) samr_close_handle(&domain_handle);
3791ed6b69aSGordon Ross out_samr_handle:
3801ed6b69aSGordon Ross 	(void) samr_close_handle(&samr_handle);
3811ed6b69aSGordon Ross 
3821ed6b69aSGordon Ross 	return (status);
3831ed6b69aSGordon Ross }
3841ed6b69aSGordon Ross 
3851ed6b69aSGordon Ross /*
3861ed6b69aSGordon Ross  * Doing "Unsecure join" (using a pre-created machine account).
3871ed6b69aSGordon Ross  * All we need to do is change the password from the default
3881ed6b69aSGordon Ross  * to a random string.
3891ed6b69aSGordon Ross  *
3901ed6b69aSGordon Ross  * Note: this is a work in progres.  Nexenta issue 11960
3911ed6b69aSGordon Ross  * (allow joining an AD domain using a pre-created computer account)
3921ed6b69aSGordon Ross  * It turns out that to change the machine account password,
3931ed6b69aSGordon Ross  * we need to use a different RPC call, performed over the
3941ed6b69aSGordon Ross  * NetLogon secure channel.  (See netr_server_password_set2)
3951ed6b69aSGordon Ross  */
3961ed6b69aSGordon Ross static DWORD
3971ed6b69aSGordon Ross mlsvc_join_noauth(smb_domainex_t *dxi,
3981ed6b69aSGordon Ross 	char *machine_name, char *machine_pw)
3991ed6b69aSGordon Ross {
4001ed6b69aSGordon Ross 	char old_pw[SMB_SAMACCT_MAXLEN];
4011ed6b69aSGordon Ross 	DWORD status;
4021ed6b69aSGordon Ross 
4031ed6b69aSGordon Ross 	/*
4041ed6b69aSGordon Ross 	 * Compose the current (default) password for the
4051ed6b69aSGordon Ross 	 * pre-created machine account, which is just the
4061ed6b69aSGordon Ross 	 * account name in lower case, truncated to 14
4071ed6b69aSGordon Ross 	 * characters.
4081ed6b69aSGordon Ross 	 */
4091ed6b69aSGordon Ross 	if (smb_gethostname(old_pw, sizeof (old_pw), SMB_CASE_LOWER) != 0)
4101ed6b69aSGordon Ross 		return (NT_STATUS_INTERNAL_ERROR);
4111ed6b69aSGordon Ross 	old_pw[14] = '\0';
4121ed6b69aSGordon Ross 
413*b3700b07SGordon Ross 	status = netr_change_password(dxi->d_dci.dc_name, machine_name,
4141ed6b69aSGordon Ross 	    old_pw, machine_pw);
4151ed6b69aSGordon Ross 	if (status != NT_STATUS_SUCCESS) {
4161ed6b69aSGordon Ross 		syslog(LOG_NOTICE,
4171ed6b69aSGordon Ross 		    "Change machine account password: %s",
4181ed6b69aSGordon Ross 		    xlate_nt_status(status));
4191ed6b69aSGordon Ross 	}
420da6c28aaSamw 	return (status);
421da6c28aaSamw }
422a0aa776eSAlan Wright 
423a0aa776eSAlan Wright void
424a0aa776eSAlan Wright mlsvc_disconnect(const char *server)
425a0aa776eSAlan Wright {
426a0aa776eSAlan Wright 	smbrdr_disconnect(server);
427a0aa776eSAlan Wright }
428