xref: /illumos-gate/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c (revision 47842382d52f28aa3173aa6b511781c322ccb6a2)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * Utility functions to support the RPC interface library.
28  */
29 
30 #include <stdio.h>
31 #include <stdarg.h>
32 #include <strings.h>
33 #include <unistd.h>
34 #include <netdb.h>
35 #include <stdlib.h>
36 #include <sys/time.h>
37 #include <sys/systm.h>
38 
39 #include <smbsrv/libsmb.h>
40 #include <smbsrv/libsmbrdr.h>
41 #include <smbsrv/libsmbns.h>
42 #include <smbsrv/libmlsvc.h>
43 #include <smbsrv/smbinfo.h>
44 #include <lsalib.h>
45 #include <samlib.h>
46 #include <smbsrv/netrauth.h>
47 
48 /* Domain join support (using MS-RPC) */
49 static boolean_t mlsvc_ntjoin_support = B_FALSE;
50 
51 extern int netr_open(char *, char *, mlsvc_handle_t *);
52 extern int netr_close(mlsvc_handle_t *);
53 extern DWORD netlogon_auth(char *, mlsvc_handle_t *, DWORD);
54 extern int mlsvc_user_getauth(char *, char *, smb_auth_info_t *);
55 
56 /*
57  * mlsvc_lookup_name
58  *
59  * This is just a wrapper for lsa_lookup_name.
60  *
61  * The memory for the sid is allocated using malloc so the caller should
62  * call free when it is no longer required.
63  */
64 uint32_t
65 mlsvc_lookup_name(char *name, smb_sid_t **sid, uint16_t *sid_type)
66 {
67 	smb_account_t account;
68 	uint32_t status;
69 
70 	status = lsa_lookup_name(name, *sid_type, &account);
71 	if (status == NT_STATUS_SUCCESS) {
72 		*sid = account.a_sid;
73 		account.a_sid = NULL;
74 		*sid_type = account.a_type;
75 		smb_account_free(&account);
76 	}
77 
78 	return (status);
79 }
80 
81 /*
82  * mlsvc_lookup_sid
83  *
84  * This is just a wrapper for lsa_lookup_sid.
85  *
86  * The allocated memory for the returned name must be freed by caller upon
87  * successful return.
88  */
89 uint32_t
90 mlsvc_lookup_sid(smb_sid_t *sid, char **name)
91 {
92 	smb_account_t ainfo;
93 	uint32_t status;
94 	int namelen;
95 
96 	if ((status = lsa_lookup_sid(sid, &ainfo)) == NT_STATUS_SUCCESS) {
97 		namelen = strlen(ainfo.a_domain) + strlen(ainfo.a_name) + 2;
98 		if ((*name = malloc(namelen)) != NULL)
99 			(void) snprintf(*name, namelen, "%s\\%s",
100 			    ainfo.a_domain, ainfo.a_name);
101 		else
102 			status = NT_STATUS_NO_MEMORY;
103 
104 		smb_account_free(&ainfo);
105 	}
106 
107 	return (status);
108 }
109 
110 DWORD
111 mlsvc_netlogon(char *server, char *domain)
112 {
113 	mlsvc_handle_t netr_handle;
114 	DWORD status;
115 
116 	if (netr_open(server, domain, &netr_handle) == 0) {
117 		status = netlogon_auth(server, &netr_handle,
118 		    NETR_FLG_INIT);
119 		(void) netr_close(&netr_handle);
120 	} else {
121 		status = NT_STATUS_OPEN_FAILED;
122 	}
123 
124 	return (status);
125 }
126 
127 /*
128  * mlsvc_join
129  *
130  * Returns NT status codes.
131  */
132 DWORD
133 mlsvc_join(smb_domain_t *dinfo, char *user, char *plain_text)
134 {
135 	smb_auth_info_t auth;
136 	int erc;
137 	DWORD status;
138 	char machine_passwd[NETR_MACHINE_ACCT_PASSWD_MAX];
139 
140 	machine_passwd[0] = '\0';
141 
142 	/*
143 	 * Ensure that the domain name is uppercase.
144 	 */
145 	(void) utf8_strupr(dinfo->d_nbdomain);
146 
147 	erc = mlsvc_logon(dinfo->d_dc, dinfo->d_nbdomain, user);
148 
149 	if (erc == AUTH_USER_GRANT) {
150 		if (mlsvc_ntjoin_support == B_FALSE) {
151 
152 			if (smb_ads_join(dinfo->d_fqdomain, user, plain_text,
153 			    machine_passwd, sizeof (machine_passwd))
154 			    == SMB_ADJOIN_SUCCESS)
155 				status = NT_STATUS_SUCCESS;
156 			else
157 				status = NT_STATUS_UNSUCCESSFUL;
158 		} else {
159 			if (mlsvc_user_getauth(dinfo->d_dc, user, &auth)
160 			    != 0) {
161 				status = NT_STATUS_INVALID_PARAMETER;
162 				return (status);
163 			}
164 
165 			status = sam_create_trust_account(dinfo->d_dc,
166 			    dinfo->d_nbdomain, &auth);
167 			if (status == NT_STATUS_SUCCESS) {
168 				(void) smb_getnetbiosname(machine_passwd,
169 				    sizeof (machine_passwd));
170 				(void) utf8_strlwr(machine_passwd);
171 			}
172 		}
173 
174 		if (status == NT_STATUS_SUCCESS) {
175 			erc = smb_setdomainprops(NULL, dinfo->d_dc,
176 			    machine_passwd);
177 			if (erc != 0)
178 				return (NT_STATUS_UNSUCCESSFUL);
179 
180 			status = mlsvc_netlogon(dinfo->d_dc, dinfo->d_nbdomain);
181 		}
182 	} else {
183 		status = NT_STATUS_LOGON_FAILURE;
184 	}
185 
186 	return (status);
187 }
188