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 (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /*
26 * Utility functions to support the RPC interface library.
27 */
28
29 #include <stdio.h>
30 #include <stdarg.h>
31 #include <strings.h>
32 #include <unistd.h>
33 #include <netdb.h>
34 #include <stdlib.h>
35 #include <sys/time.h>
36 #include <sys/systm.h>
37 #include <syslog.h>
38
39 #include <smbsrv/libsmb.h>
40 #include <smbsrv/libsmbns.h>
41 #include <smbsrv/libmlsvc.h>
42 #include <smbsrv/libsmbrdr.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
55 DWORD
mlsvc_netlogon(char * server,char * domain)56 mlsvc_netlogon(char *server, char *domain)
57 {
58 mlsvc_handle_t netr_handle;
59 DWORD status;
60
61 if (netr_open(server, domain, &netr_handle) == 0) {
62 if ((status = netlogon_auth(server, &netr_handle,
63 NETR_FLG_INIT)) != NT_STATUS_SUCCESS)
64 syslog(LOG_NOTICE, "Failed to establish NETLOGON "
65 "credential chain");
66 (void) netr_close(&netr_handle);
67 } else {
68 status = NT_STATUS_OPEN_FAILED;
69 }
70
71 return (status);
72 }
73
74 /*
75 * Joins the specified domain by creating a machine account on
76 * the selected domain controller.
77 *
78 * Disconnect any existing connection with the domain controller.
79 * This will ensure that no stale connection will be used, it will
80 * also pickup any configuration changes in either side by trying
81 * to establish a new connection.
82 *
83 * Returns NT status codes.
84 */
85 DWORD
mlsvc_join(smb_domainex_t * dxi,char * user,char * plain_text)86 mlsvc_join(smb_domainex_t *dxi, char *user, char *plain_text)
87 {
88 int erc;
89 DWORD status;
90 char machine_passwd[NETR_MACHINE_ACCT_PASSWD_MAX];
91 smb_adjoin_status_t err;
92 smb_domain_t *domain;
93
94 machine_passwd[0] = '\0';
95
96 domain = &dxi->d_primary;
97
98 mlsvc_disconnect(dxi->d_dc);
99
100 erc = smbrdr_logon(dxi->d_dc, domain->di_nbname, user);
101
102 if (erc == AUTH_USER_GRANT) {
103 if (mlsvc_ntjoin_support == B_FALSE) {
104
105 if ((err = smb_ads_join(domain->di_fqname, user,
106 plain_text, machine_passwd,
107 sizeof (machine_passwd))) == SMB_ADJOIN_SUCCESS) {
108 status = NT_STATUS_SUCCESS;
109 } else {
110 smb_ads_join_errmsg(err);
111 status = NT_STATUS_UNSUCCESSFUL;
112 }
113 } else {
114
115 status = sam_create_trust_account(dxi->d_dc,
116 domain->di_nbname);
117 if (status == NT_STATUS_SUCCESS) {
118 (void) smb_getnetbiosname(machine_passwd,
119 sizeof (machine_passwd));
120 (void) smb_strlwr(machine_passwd);
121 }
122 }
123
124 if (status == NT_STATUS_SUCCESS) {
125 erc = smb_setdomainprops(NULL, dxi->d_dc,
126 machine_passwd);
127 if (erc != 0) {
128 syslog(LOG_NOTICE,
129 "Failed to update configuration");
130 bzero(machine_passwd, sizeof (machine_passwd));
131 return (NT_STATUS_UNSUCCESSFUL);
132 }
133
134 status = mlsvc_netlogon(dxi->d_dc, domain->di_nbname);
135 }
136 } else {
137 status = NT_STATUS_LOGON_FAILURE;
138 }
139
140 bzero(machine_passwd, sizeof (machine_passwd));
141 return (status);
142 }
143
144 void
mlsvc_disconnect(const char * server)145 mlsvc_disconnect(const char *server)
146 {
147 smbrdr_disconnect(server);
148 }
149