xref: /illumos-gate/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c (revision 0bb073995ac5a95bd35f2dd790df1ea3d8c2d507)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/errno.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <strings.h>
30 #include <string.h>
31 #include <rpc/xdr.h>
32 #include <synch.h>
33 #include <pthread.h>
34 #include <smbsrv/smb_door_svc.h>
35 #include <smbsrv/smb_common_door.h>
36 #include <smbsrv/libsmb.h>
37 #include <smbsrv/libmlsvc.h>
38 
39 void dssetup_initialize(void);
40 void srvsvc_initialize(void);
41 void wkssvc_initialize(void);
42 void lsarpc_initialize(void);
43 void logr_initialize(void);
44 void netr_initialize(void);
45 void samr_initialize(void);
46 void svcctl_initialize(void);
47 void winreg_initialize(void);
48 int srvsvc_gettime(unsigned long *);
49 
50 static void *mlsvc_keepalive(void *);
51 
52 static pthread_t mlsvc_keepalive_thr;
53 #define	MLSVC_KEEPALIVE_INTERVAL	(10 * 60)	/* 10 minutes */
54 
55 /*
56  * Door fd for downcalls to the smbsrv kernel door service.
57  * smbsrv will make an upcall to smbd during initialization to
58  * provide this file descriptor.
59  */
60 static int mlsvc_door_fd = -1;
61 static mutex_t mlsvc_fd_mutex;
62 
63 /*
64  * All mlrpc initialization is invoked from here.
65  * Returns 0 upon success.  Otherwise, returns -1.
66  */
67 int
68 mlsvc_init(void)
69 {
70 	pthread_attr_t tattr;
71 	int rc;
72 
73 	srvsvc_initialize();
74 	wkssvc_initialize();
75 	lsarpc_initialize();
76 	netr_initialize();
77 	dssetup_initialize();
78 	samr_initialize();
79 	svcctl_initialize();
80 	winreg_initialize();
81 	logr_initialize();
82 
83 	(void) pthread_attr_init(&tattr);
84 	(void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
85 	rc = pthread_create(&mlsvc_keepalive_thr, &tattr,
86 	    mlsvc_keepalive, 0);
87 	(void) pthread_attr_destroy(&tattr);
88 	return (rc);
89 }
90 
91 /*ARGSUSED*/
92 static void *
93 mlsvc_keepalive(void *arg)
94 {
95 	unsigned long t;
96 	nt_domain_t *domain;
97 
98 	for (;;) {
99 		(void) sleep(MLSVC_KEEPALIVE_INTERVAL);
100 
101 		if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) {
102 			domain = nt_domain_lookupbytype(NT_DOMAIN_PRIMARY);
103 			if (domain == NULL)
104 				(void) lsa_query_primary_domain_info();
105 			(void) srvsvc_gettime(&t);
106 		}
107 	}
108 
109 	/*NOTREACHED*/
110 	return (NULL);
111 }
112 
113 void
114 mlsvc_set_door_fd(int fd)
115 {
116 	(void) mutex_lock(&mlsvc_fd_mutex);
117 	mlsvc_door_fd = fd;
118 	(void) mutex_unlock(&mlsvc_fd_mutex);
119 }
120 
121 int
122 mlsvc_get_door_fd(void)
123 {
124 	int fd;
125 
126 	(void) mutex_lock(&mlsvc_fd_mutex);
127 	fd = mlsvc_door_fd;
128 	(void) mutex_unlock(&mlsvc_fd_mutex);
129 
130 	return (fd);
131 }
132 
133 uint64_t
134 mlsvc_get_num_users(void)
135 {
136 	door_arg_t arg;
137 	char *buf;
138 	size_t len;
139 	int64_t n_users = 0;
140 	int fd;
141 
142 	if ((fd = mlsvc_get_door_fd()) < 0)
143 		return (0);
144 
145 	if ((buf = smb_dr_set_opcode(SMB_KDR_USER_NUM, &len)) == NULL)
146 		return (0);
147 
148 	smb_dr_clnt_setup(&arg, buf, len);
149 
150 	if (smb_dr_clnt_call(fd, &arg) == 0) {
151 		buf = arg.rbuf + SMB_DR_DATA_OFFSET;
152 		len = arg.rsize - SMB_DR_DATA_OFFSET;
153 
154 		if (smb_dr_decode_common(buf, len, xdr_uint32_t, &n_users) != 0)
155 			n_users = 0;
156 	}
157 
158 	smb_dr_clnt_cleanup(&arg);
159 	return (n_users);
160 }
161 
162 /*
163  * The calling function must free the output parameter 'users'.
164  */
165 int
166 mlsvc_get_user_list(int offset, smb_dr_ulist_t *users)
167 {
168 	door_arg_t arg;
169 	char *buf;
170 	size_t len;
171 	uint_t opcode = SMB_KDR_USER_LIST;
172 	int fd, rc = -1;
173 
174 	bzero(users, sizeof (smb_dr_ulist_t));
175 
176 	if ((fd = mlsvc_get_door_fd()) < 0)
177 		return (-1);
178 
179 	buf = smb_dr_encode_common(opcode, &offset, xdr_uint32_t, &len);
180 	if (buf == NULL)
181 		return (-1);
182 
183 	smb_dr_clnt_setup(&arg, buf, len);
184 
185 	if (smb_dr_clnt_call(fd, &arg) == 0) {
186 		buf = arg.rbuf + SMB_DR_DATA_OFFSET;
187 		len = arg.rsize - SMB_DR_DATA_OFFSET;
188 
189 		rc = smb_dr_decode_common(buf, len, xdr_smb_dr_ulist_t, users);
190 		if (rc == 0)
191 			rc = users->dul_cnt;
192 	}
193 
194 	smb_dr_clnt_cleanup(&arg);
195 	return (rc);
196 }
197 
198 /*
199  * Downcall to the kernel that is executed upon share enable and disable.
200  */
201 int
202 mlsvc_set_share(int shrop, char *path, char *sharename)
203 {
204 	door_arg_t arg;
205 	char *buf;
206 	size_t len;
207 	smb_dr_kshare_t kshare;
208 	int fd, rc = 0;
209 
210 	if ((shrop != SMB_SHROP_ADD) && (shrop != SMB_SHROP_DELETE))
211 		return (EINVAL);
212 
213 	if ((fd = mlsvc_get_door_fd()) < 0)
214 		return (EBADF);
215 
216 	kshare.k_op = shrop;
217 	kshare.k_path = strdup(path);
218 	kshare.k_sharename = strdup(sharename);
219 
220 	buf = smb_dr_encode_kshare(&kshare, &len);
221 	free(kshare.k_path);
222 	free(kshare.k_sharename);
223 
224 	if (buf == NULL)
225 		return (ENOMEM);
226 
227 	smb_dr_clnt_setup(&arg, buf, len);
228 
229 	if (smb_dr_clnt_call(fd, &arg) == 0) {
230 		buf = arg.rbuf + SMB_DR_DATA_OFFSET;
231 		len = arg.rsize - SMB_DR_DATA_OFFSET;
232 
233 		if (smb_dr_decode_common(buf, len, xdr_int32_t, &rc) != 0)
234 			rc = ENOMEM;
235 	}
236 
237 	smb_dr_clnt_cleanup(&arg);
238 	return (rc);
239 }
240