Print this page
1575 untangle libmlrpc ... (smbsrv)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c
+++ new/usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
25 25 */
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
26 26
27 27 /*
28 28 * Local Security Authority RPC (LSAR) server-side interface.
29 29 */
30 30
31 31 #include <unistd.h>
32 32 #include <strings.h>
33 33 #include <pwd.h>
34 34 #include <grp.h>
35 35
36 +#include <libmlrpc/libmlrpc.h>
36 37 #include <smbsrv/libsmb.h>
37 -#include <smbsrv/libmlrpc.h>
38 38 #include <smbsrv/libmlsvc.h>
39 39 #include <smbsrv/ndl/lsarpc.ndl>
40 40 #include <lsalib.h>
41 41 #include <smbsrv/smbinfo.h>
42 42 #include <smbsrv/nmpipes.h>
43 43 #include <smbsrv/ntlocale.h>
44 44
45 45 struct local_group_table {
46 46 WORD sid_name_use;
47 47 WORD domain_ix;
48 48 char *sid;
49 49 char *name;
50 50 };
51 51
52 52 static int lsarpc_key_domain;
53 53 static int lsarpc_key_account;
54 54
55 55 static int lsarpc_call_stub(ndr_xa_t *mxa);
56 56
57 57 static int lsarpc_s_CloseHandle(void *, ndr_xa_t *);
58 58 static int lsarpc_s_QuerySecurityObject(void *, ndr_xa_t *);
59 59 static int lsarpc_s_EnumAccounts(void *, ndr_xa_t *);
60 60 static int lsarpc_s_EnumTrustedDomain(void *, ndr_xa_t *);
61 61 static int lsarpc_s_EnumTrustedDomainsEx(void *, ndr_xa_t *);
62 62 static int lsarpc_s_OpenAccount(void *, ndr_xa_t *);
63 63 static int lsarpc_s_EnumPrivsAccount(void *, ndr_xa_t *);
64 64 static int lsarpc_s_LookupPrivValue(void *, ndr_xa_t *);
65 65 static int lsarpc_s_LookupPrivName(void *, ndr_xa_t *);
66 66 static int lsarpc_s_LookupPrivDisplayName(void *, ndr_xa_t *);
67 67 static int lsarpc_s_CreateSecret(void *, ndr_xa_t *);
68 68 static int lsarpc_s_OpenSecret(void *, ndr_xa_t *);
69 69 static int lsarpc_s_QueryInfoPolicy(void *, ndr_xa_t *);
70 70 static int lsarpc_s_OpenDomainHandle(void *, ndr_xa_t *);
71 71 static int lsarpc_s_OpenDomainHandle(void *, ndr_xa_t *);
72 72 static int lsarpc_s_LookupSids(void *, ndr_xa_t *);
73 73 static int lsarpc_s_LookupNames(void *, ndr_xa_t *);
74 74 static int lsarpc_s_GetConnectedUser(void *, ndr_xa_t *);
75 75 static int lsarpc_s_LookupSids2(void *, ndr_xa_t *);
76 76 static int lsarpc_s_LookupSids3(void *, ndr_xa_t *);
77 77 static int lsarpc_s_LookupNames2(void *, ndr_xa_t *);
78 78 static int lsarpc_s_LookupNames3(void *, ndr_xa_t *);
79 79 static int lsarpc_s_LookupNames4(void *, ndr_xa_t *);
80 80
81 81 static DWORD lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *,
82 82 ndr_xa_t *);
83 83 static DWORD lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *,
84 84 ndr_xa_t *);
85 85 static int lsarpc_s_UpdateDomainTable(ndr_xa_t *,
86 86 smb_account_t *, struct mslsa_domain_table *, DWORD *);
87 87
88 88 static ndr_stub_table_t lsarpc_stub_table[] = {
89 89 { lsarpc_s_CloseHandle, LSARPC_OPNUM_CloseHandle },
90 90 { lsarpc_s_QuerySecurityObject, LSARPC_OPNUM_QuerySecurityObject },
91 91 { lsarpc_s_EnumAccounts, LSARPC_OPNUM_EnumerateAccounts },
92 92 { lsarpc_s_EnumTrustedDomain, LSARPC_OPNUM_EnumTrustedDomain },
93 93 { lsarpc_s_EnumTrustedDomainsEx, LSARPC_OPNUM_EnumTrustedDomainsEx },
94 94 { lsarpc_s_OpenAccount, LSARPC_OPNUM_OpenAccount },
95 95 { lsarpc_s_EnumPrivsAccount, LSARPC_OPNUM_EnumPrivsAccount },
96 96 { lsarpc_s_LookupPrivValue, LSARPC_OPNUM_LookupPrivValue },
97 97 { lsarpc_s_LookupPrivName, LSARPC_OPNUM_LookupPrivName },
98 98 { lsarpc_s_LookupPrivDisplayName, LSARPC_OPNUM_LookupPrivDisplayName },
99 99 { lsarpc_s_CreateSecret, LSARPC_OPNUM_CreateSecret },
100 100 { lsarpc_s_OpenSecret, LSARPC_OPNUM_OpenSecret },
101 101 { lsarpc_s_QueryInfoPolicy, LSARPC_OPNUM_QueryInfoPolicy },
102 102 { lsarpc_s_OpenDomainHandle, LSARPC_OPNUM_OpenPolicy },
103 103 { lsarpc_s_OpenDomainHandle, LSARPC_OPNUM_OpenPolicy2 },
104 104 { lsarpc_s_LookupSids, LSARPC_OPNUM_LookupSids },
105 105 { lsarpc_s_LookupNames, LSARPC_OPNUM_LookupNames },
106 106 { lsarpc_s_GetConnectedUser, LSARPC_OPNUM_GetConnectedUser },
107 107 { lsarpc_s_LookupSids2, LSARPC_OPNUM_LookupSids2 },
108 108 { lsarpc_s_LookupSids3, LSARPC_OPNUM_LookupSids3 },
109 109 { lsarpc_s_LookupNames2, LSARPC_OPNUM_LookupNames2 },
110 110 { lsarpc_s_LookupNames3, LSARPC_OPNUM_LookupNames3 },
111 111 { lsarpc_s_LookupNames4, LSARPC_OPNUM_LookupNames4 },
112 112 {0}
113 113 };
114 114
115 115 static ndr_service_t lsarpc_service = {
116 116 "LSARPC", /* name */
117 117 "Local Security Authority", /* desc */
118 118 "\\lsarpc", /* endpoint */
119 119 PIPE_LSASS, /* sec_addr_port */
120 120 "12345778-1234-abcd-ef00-0123456789ab", 0, /* abstract */
121 121 NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */
122 122 0, /* no bind_instance_size */
123 123 NULL, /* no bind_req() */
124 124 NULL, /* no unbind_and_close() */
125 125 lsarpc_call_stub, /* call_stub() */
126 126 &TYPEINFO(lsarpc_interface), /* interface ti */
127 127 lsarpc_stub_table /* stub_table */
128 128 };
129 129
130 130 /*
131 131 * lsarpc_initialize
132 132 *
133 133 * This function registers the LSA RPC interface with the RPC runtime
134 134 * library. It must be called in order to use either the client side
135 135 * or the server side functions.
136 136 */
137 137 void
138 138 lsarpc_initialize(void)
139 139 {
140 140 (void) ndr_svc_register(&lsarpc_service);
141 141 }
142 142
143 143 /*
144 144 * Custom call_stub to set the stream string policy.
145 145 */
146 146 static int
147 147 lsarpc_call_stub(ndr_xa_t *mxa)
148 148 {
149 149 NDS_SETF(&mxa->send_nds, NDS_F_NOTERM);
150 150 NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM);
151 151
152 152 return (ndr_generic_call_stub(mxa));
153 153 }
154 154
155 155 /*
156 156 * lsarpc_s_OpenDomainHandle opnum=0x06
157 157 *
158 158 * This is a request to open the LSA (OpenPolicy and OpenPolicy2).
159 159 * The client is looking for an LSA domain handle.
160 160 */
161 161 static int
162 162 lsarpc_s_OpenDomainHandle(void *arg, ndr_xa_t *mxa)
163 163 {
164 164 struct mslsa_OpenPolicy2 *param = arg;
165 165 ndr_hdid_t *id;
166 166
167 167 if ((id = ndr_hdalloc(mxa, &lsarpc_key_domain)) != NULL) {
168 168 bcopy(id, ¶m->domain_handle, sizeof (mslsa_handle_t));
169 169 param->status = NT_STATUS_SUCCESS;
170 170 } else {
171 171 bzero(¶m->domain_handle, sizeof (mslsa_handle_t));
172 172 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
173 173 }
174 174
175 175 return (NDR_DRC_OK);
176 176 }
177 177
178 178 /*
179 179 * lsarpc_s_CloseHandle opnum=0x00
180 180 *
181 181 * This is a request to close the LSA interface specified by the handle.
182 182 * We don't track handles (yet), so just zero out the handle and return
183 183 * NDR_DRC_OK. Setting the handle to zero appears to be standard
184 184 * behaviour and someone may rely on it, i.e. we do on the client side.
185 185 */
186 186 static int
187 187 lsarpc_s_CloseHandle(void *arg, ndr_xa_t *mxa)
188 188 {
189 189 struct mslsa_CloseHandle *param = arg;
190 190 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
191 191
192 192 ndr_hdfree(mxa, id);
193 193
194 194 bzero(¶m->result_handle, sizeof (param->result_handle));
195 195 param->status = NT_STATUS_SUCCESS;
196 196 return (NDR_DRC_OK);
197 197 }
198 198
199 199 /*
200 200 * lsarpc_s_QuerySecurityObject
201 201 */
202 202 /*ARGSUSED*/
203 203 static int
204 204 lsarpc_s_QuerySecurityObject(void *arg, ndr_xa_t *mxa)
205 205 {
206 206 struct mslsa_QuerySecurityObject *param = arg;
207 207
208 208 bzero(param, sizeof (struct mslsa_QuerySecurityObject));
209 209 param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
210 210
211 211 return (NDR_DRC_OK);
212 212 }
213 213
214 214 /*
215 215 * lsarpc_s_EnumAccounts
216 216 *
217 217 * Enumerate the list of local accounts SIDs. The client should supply
218 218 * a valid OpenPolicy2 handle. The enum_context is used to support
219 219 * multiple enumeration calls to obtain the complete list of SIDs.
220 220 * It should be set to 0 on the first call and passed unchanged on
221 221 * subsequent calls until there are no more accounts - the server will
222 222 * return STATUS_NO_MORE_ENTRIES.
223 223 *
224 224 * For now just set the status to access-denied. Note that we still have
225 225 * to provide a valid address for enum_buf because it's a reference and
226 226 * the marshalling rules require that references must not be null.
227 227 * The enum_context is used to support multiple
228 228 */
229 229 static int
230 230 lsarpc_s_EnumAccounts(void *arg, ndr_xa_t *mxa)
231 231 {
232 232 struct mslsa_EnumerateAccounts *param = arg;
233 233 struct mslsa_EnumAccountBuf *enum_buf;
234 234
235 235 bzero(param, sizeof (struct mslsa_EnumerateAccounts));
236 236
237 237 enum_buf = NDR_NEW(mxa, struct mslsa_EnumAccountBuf);
238 238 if (enum_buf == NULL) {
239 239 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
240 240 return (NDR_DRC_OK);
241 241 }
242 242
243 243 bzero(enum_buf, sizeof (struct mslsa_EnumAccountBuf));
244 244 param->enum_buf = enum_buf;
245 245 param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
246 246 return (NDR_DRC_OK);
247 247 }
248 248
249 249
250 250 /*
251 251 * lsarpc_s_EnumTrustedDomain
252 252 *
253 253 * This is the server side function for handling requests to enumerate
254 254 * the list of trusted domains: currently held in the NT domain database.
255 255 * This call requires an OpenPolicy2 handle. The enum_context is used to
256 256 * support multiple enumeration calls to obtain the complete list.
257 257 * It should be set to 0 on the first call and passed unchanged on
258 258 * subsequent calls until there are no more accounts - the server will
259 259 * return STATUS_NO_MORE_ENTRIES.
260 260 *
261 261 * For now just set the status to access-denied. Note that we still have
262 262 * to provide a valid address for enum_buf because it's a reference and
263 263 * the marshalling rules require that references must not be null.
264 264 */
265 265 static int
266 266 lsarpc_s_EnumTrustedDomain(void *arg, ndr_xa_t *mxa)
267 267 {
268 268 struct mslsa_EnumTrustedDomain *param = arg;
269 269 struct mslsa_EnumTrustedDomainBuf *enum_buf;
270 270
271 271 bzero(param, sizeof (struct mslsa_EnumTrustedDomain));
272 272
273 273 enum_buf = NDR_NEW(mxa, struct mslsa_EnumTrustedDomainBuf);
274 274 if (enum_buf == NULL) {
275 275 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
276 276 return (NDR_DRC_OK);
277 277 }
278 278
279 279 bzero(enum_buf, sizeof (struct mslsa_EnumTrustedDomainBuf));
280 280 param->enum_buf = enum_buf;
281 281 param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
282 282 return (NDR_DRC_OK);
283 283 }
284 284
285 285 /*
286 286 * lsarpc_s_EnumTrustedDomainsEx
287 287 *
288 288 * This is the server side function for handling requests to enumerate
289 289 * the list of trusted domains: currently held in the NT domain database.
290 290 * This call requires an OpenPolicy2 handle. The enum_context is used to
291 291 * support multiple enumeration calls to obtain the complete list.
292 292 * It should be set to 0 on the first call and passed unchanged on
293 293 * subsequent calls until there are no more accounts - the server will
294 294 * return STATUS_NO_MORE_ENTRIES.
295 295 *
296 296 * For now just set the status to access-denied. Note that we still have
297 297 * to provide a valid address for enum_buf because it's a reference and
298 298 * the marshalling rules require that references must not be null.
299 299 */
300 300 static int
301 301 lsarpc_s_EnumTrustedDomainsEx(void *arg, ndr_xa_t *mxa)
302 302 {
303 303 struct mslsa_EnumTrustedDomainEx *param = arg;
304 304 struct mslsa_EnumTrustedDomainBufEx *enum_buf;
305 305
306 306 bzero(param, sizeof (struct mslsa_EnumTrustedDomainEx));
307 307
308 308 enum_buf = NDR_NEW(mxa, struct mslsa_EnumTrustedDomainBufEx);
309 309 if (enum_buf == NULL) {
310 310 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
311 311 return (NDR_DRC_OK);
312 312 }
313 313
314 314 bzero(enum_buf, sizeof (struct mslsa_EnumTrustedDomainBufEx));
315 315 param->enum_buf = enum_buf;
316 316 param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
317 317 return (NDR_DRC_OK);
318 318 }
319 319
320 320 /*
321 321 * lsarpc_s_OpenAccount
322 322 *
323 323 * This is a request to open an account handle.
324 324 */
325 325 static int
326 326 lsarpc_s_OpenAccount(void *arg, ndr_xa_t *mxa)
327 327 {
328 328 struct mslsa_OpenAccount *param = arg;
329 329 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
330 330 ndr_handle_t *hd;
331 331
332 332 hd = ndr_hdlookup(mxa, id);
333 333 if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) {
334 334 bzero(param, sizeof (struct mslsa_OpenAccount));
335 335 param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
336 336 return (NDR_DRC_OK);
337 337 }
338 338
339 339 if ((id = ndr_hdalloc(mxa, &lsarpc_key_account)) != NULL) {
340 340 bcopy(id, ¶m->account_handle, sizeof (mslsa_handle_t));
341 341 param->status = NT_STATUS_SUCCESS;
342 342 } else {
343 343 bzero(¶m->account_handle, sizeof (mslsa_handle_t));
344 344 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
345 345 }
346 346
347 347 return (NDR_DRC_OK);
348 348 }
349 349
350 350
351 351 /*
352 352 * lsarpc_s_EnumPrivsAccount
353 353 *
354 354 * This is the server side function for handling requests for account
355 355 * privileges. For now just set the status to not-supported status and
356 356 * return NDR_DRC_OK. Note that we still have to provide a valid
357 357 * address for enum_buf because it's a reference and the marshalling
358 358 * rules require that references must not be null.
359 359 */
360 360 /*ARGSUSED*/
361 361 static int
362 362 lsarpc_s_EnumPrivsAccount(void *arg, ndr_xa_t *mxa)
363 363 {
364 364 struct mslsa_EnumPrivsAccount *param = arg;
365 365
366 366 bzero(param, sizeof (struct mslsa_EnumPrivsAccount));
367 367 param->status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED);
368 368 return (NDR_DRC_OK);
369 369 }
370 370
371 371 /*
372 372 * lsarpc_s_LookupPrivValue
373 373 *
374 374 * Server side function used to map a privilege name to a locally unique
375 375 * identifier (LUID).
376 376 */
377 377 /*ARGSUSED*/
378 378 static int
379 379 lsarpc_s_LookupPrivValue(void *arg, ndr_xa_t *mxa)
380 380 {
381 381 struct mslsa_LookupPrivValue *param = arg;
382 382 smb_privinfo_t *pi;
383 383
384 384 if ((pi = smb_priv_getbyname((char *)param->name.str)) == NULL) {
385 385 bzero(param, sizeof (struct mslsa_LookupPrivValue));
386 386 param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE);
387 387 return (NDR_DRC_OK);
388 388 }
389 389
390 390 param->luid.low_part = pi->id;
391 391 param->luid.high_part = 0;
392 392 param->status = NT_STATUS_SUCCESS;
393 393 return (NDR_DRC_OK);
394 394 }
395 395
396 396 /*
397 397 * lsarpc_s_LookupPrivName
398 398 *
399 399 * Server side function used to map a locally unique identifier (LUID)
400 400 * to the appropriate privilege name string.
401 401 */
402 402 static int
403 403 lsarpc_s_LookupPrivName(void *arg, ndr_xa_t *mxa)
404 404 {
405 405 struct mslsa_LookupPrivName *param = arg;
406 406 smb_privinfo_t *pi;
407 407 int rc;
408 408
409 409 if ((pi = smb_priv_getbyvalue(param->luid.low_part)) == NULL) {
410 410 bzero(param, sizeof (struct mslsa_LookupPrivName));
411 411 param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE);
412 412 return (NDR_DRC_OK);
413 413 }
414 414
415 415 param->name = NDR_NEW(mxa, mslsa_string_t);
416 416 if (param->name == NULL) {
417 417 bzero(param, sizeof (struct mslsa_LookupPrivName));
418 418 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
419 419 return (NDR_DRC_OK);
420 420 }
421 421
422 422 rc = NDR_MSTRING(mxa, pi->name, (ndr_mstring_t *)param->name);
423 423 if (rc == -1) {
424 424 bzero(param, sizeof (struct mslsa_LookupPrivName));
425 425 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
426 426 return (NDR_DRC_OK);
427 427 }
428 428
429 429 param->status = NT_STATUS_SUCCESS;
430 430 return (NDR_DRC_OK);
431 431 }
432 432
433 433 /*
434 434 * lsarpc_s_LookupPrivDisplayName
435 435 *
436 436 * This is the server side function for handling requests for account
437 437 * privileges. For now just set the status to not-supported status and
438 438 * return NDR_DRC_OK.
439 439 */
440 440 static int
441 441 lsarpc_s_LookupPrivDisplayName(void *arg, ndr_xa_t *mxa)
442 442 {
443 443 struct mslsa_LookupPrivDisplayName *param = arg;
444 444 smb_privinfo_t *pi;
445 445 int rc;
446 446
447 447 if ((pi = smb_priv_getbyname((char *)param->name.str)) == NULL) {
448 448 bzero(param, sizeof (struct mslsa_LookupPrivDisplayName));
449 449 param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE);
450 450 return (NDR_DRC_OK);
451 451 }
452 452
453 453 param->display_name = NDR_NEW(mxa, mslsa_string_t);
454 454 if (param->display_name == NULL) {
455 455 bzero(param, sizeof (struct mslsa_LookupPrivDisplayName));
456 456 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
457 457 return (NDR_DRC_OK);
458 458 }
459 459
460 460 rc = NDR_MSTRING(mxa, pi->display_name,
461 461 (ndr_mstring_t *)param->display_name);
462 462 if (rc == -1) {
463 463 bzero(param, sizeof (struct mslsa_LookupPrivDisplayName));
464 464 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
465 465 return (NDR_DRC_OK);
466 466 }
467 467
468 468 param->language_ret = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
469 469 param->status = NT_STATUS_SUCCESS;
470 470 return (NDR_DRC_OK);
471 471 }
472 472
473 473 static int
474 474 lsarpc_s_CreateSecret(void *arg, ndr_xa_t *mxa)
475 475 {
476 476 struct mslsa_CreateSecret *param = arg;
477 477 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
478 478 ndr_handle_t *hd;
479 479
480 480 hd = ndr_hdlookup(mxa, id);
481 481 if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) {
482 482 bzero(param, sizeof (struct mslsa_OpenAccount));
483 483 param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
484 484 return (NDR_DRC_OK);
485 485 }
486 486
487 487 bzero(¶m->secret_handle, sizeof (mslsa_handle_t));
488 488 param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
489 489 return (NDR_DRC_OK);
490 490 }
491 491
492 492 static int
493 493 lsarpc_s_OpenSecret(void *arg, ndr_xa_t *mxa)
494 494 {
495 495 struct mslsa_OpenSecret *param = arg;
496 496 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
497 497 ndr_handle_t *hd;
498 498
499 499 hd = ndr_hdlookup(mxa, id);
500 500 if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) {
501 501 bzero(param, sizeof (struct mslsa_OpenAccount));
502 502 param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
503 503 return (NDR_DRC_OK);
504 504 }
505 505
506 506 bzero(¶m->secret_handle, sizeof (mslsa_handle_t));
507 507 param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
508 508 return (NDR_DRC_OK);
509 509 }
510 510
511 511 /*
512 512 * lsarpc_s_GetConnectedUser
513 513 *
514 514 * Return the account name and NetBIOS domain name for the user making
515 515 * the request. The hostname field should be ignored by the server.
516 516 *
517 517 * Note: MacOS uses this, whether we're a domain member or not.
518 518 */
519 519 static int
520 520 lsarpc_s_GetConnectedUser(void *arg, ndr_xa_t *mxa)
521 521 {
522 522 struct mslsa_GetConnectedUser *param = arg;
523 523 smb_netuserinfo_t *user = mxa->pipe->np_user;
524 524 DWORD status = NT_STATUS_SUCCESS;
525 525 int rc1;
526 526 int rc2;
527 527
528 528 param->owner = NDR_NEW(mxa, struct mslsa_string_desc);
529 529 param->domain = NDR_NEW(mxa, struct mslsa_DomainName);
530 530 if (param->owner == NULL || param->domain == NULL) {
531 531 status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
532 532 param->status = status;
533 533 return (NDR_DRC_OK);
534 534 }
535 535
536 536 param->domain->name = NDR_NEW(mxa, struct mslsa_string_desc);
537 537 if (param->domain->name == NULL) {
538 538 status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
539 539 param->status = status;
540 540 return (NDR_DRC_OK);
541 541 }
542 542
543 543 rc1 = NDR_MSTRING(mxa, user->ui_account,
544 544 (ndr_mstring_t *)param->owner);
545 545 rc2 = NDR_MSTRING(mxa, user->ui_domain,
546 546 (ndr_mstring_t *)param->domain->name);
547 547
548 548 if (rc1 == -1 || rc2 == -1)
549 549 status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
550 550
551 551 param->status = status;
552 552 return (NDR_DRC_OK);
553 553 }
554 554
555 555
556 556 /*
557 557 * lsarpc_s_QueryInfoPolicy
558 558 *
559 559 * This is the server side function for handling LSA information policy
560 560 * queries. Currently, we only support primary domain and account
561 561 * domain queries. This is just a front end to switch on the request
562 562 * and hand it off to the appropriate function to actually deal with
563 563 * obtaining and building the response.
564 564 */
565 565 static int
566 566 lsarpc_s_QueryInfoPolicy(void *arg, ndr_xa_t *mxa)
567 567 {
568 568 struct mslsa_QueryInfoPolicy *param = arg;
569 569 union mslsa_PolicyInfoResUnion *ru = ¶m->ru;
570 570 int security_mode;
571 571 DWORD status;
572 572
573 573 param->switch_value = param->info_class;
574 574
575 575 switch (param->info_class) {
576 576 case MSLSA_POLICY_AUDIT_EVENTS_INFO:
577 577 ru->audit_events.enabled = 0;
578 578 ru->audit_events.count = 1;
579 579 ru->audit_events.settings
580 580 = NDR_MALLOC(mxa, sizeof (DWORD));
581 581 bzero(ru->audit_events.settings, sizeof (DWORD));
582 582 status = NT_STATUS_SUCCESS;
583 583 break;
584 584
585 585 case MSLSA_POLICY_PRIMARY_DOMAIN_INFO:
586 586 status = lsarpc_s_PrimaryDomainInfo(&ru->pd_info, mxa);
587 587 break;
588 588
589 589 case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO:
590 590 status = lsarpc_s_AccountDomainInfo(&ru->ad_info, mxa);
591 591 break;
592 592
593 593 case MSLSA_POLICY_SERVER_ROLE_INFO:
594 594 security_mode = smb_config_get_secmode();
595 595
596 596 if (security_mode == SMB_SECMODE_DOMAIN)
597 597 ru->server_role.role = LSA_ROLE_MEMBER_SERVER;
598 598 else
599 599 ru->server_role.role = LSA_ROLE_STANDALONE_SERVER;
600 600
601 601 ru->server_role.pad = 0;
602 602 status = NT_STATUS_SUCCESS;
603 603 break;
604 604
605 605 default:
606 606 bzero(param, sizeof (struct mslsa_QueryInfoPolicy));
607 607 param->status = NT_SC_ERROR(NT_STATUS_INVALID_INFO_CLASS);
608 608 return (NDR_DRC_OK);
609 609 }
610 610
611 611 if (status != NT_STATUS_SUCCESS)
612 612 param->status = NT_SC_ERROR(status);
613 613 else
614 614 param->status = NT_STATUS_SUCCESS;
615 615 param->address = (DWORD)(uintptr_t)ru;
616 616
617 617 return (NDR_DRC_OK);
618 618 }
619 619
620 620
621 621 /*
622 622 * lsarpc_s_PrimaryDomainInfo
623 623 *
624 624 * Service primary domain policy queries. In domain mode, return the
625 625 * primary domain name and SID. In workgroup mode, return the local
626 626 * hostname and local domain SID.
627 627 *
628 628 * Note: info is zeroed on entry to ensure the SID and name do not
629 629 * contain spurious values if an error is returned.
630 630 */
631 631 static DWORD
632 632 lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *info,
633 633 ndr_xa_t *mxa)
634 634 {
635 635 smb_domain_t di;
636 636 boolean_t found;
637 637 int rc;
638 638
639 639 bzero(info, sizeof (struct mslsa_PrimaryDomainInfo));
640 640
641 641 if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
642 642 found = smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di);
643 643 else
644 644 found = smb_domain_lookup_type(SMB_DOMAIN_PRIMARY, &di);
645 645
646 646 if (!found)
647 647 return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
648 648
649 649 rc = NDR_MSTRING(mxa, di.di_nbname, (ndr_mstring_t *)&info->name);
650 650 info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, di.di_binsid);
651 651
652 652 if ((rc == -1) || (info->sid == NULL))
653 653 return (NT_STATUS_NO_MEMORY);
654 654
655 655 return (NT_STATUS_SUCCESS);
656 656 }
657 657
658 658
659 659 /*
660 660 * lsarpc_s_AccountDomainInfo
661 661 *
662 662 * Service account domain policy queries. We return our local domain
663 663 * information so that the client knows who to query for information
664 664 * on local names and SIDs. The domain name is the local hostname.
665 665 *
666 666 * Note: info is zeroed on entry to ensure the SID and name do not
667 667 * contain spurious values if an error is returned.
668 668 */
669 669 static DWORD
670 670 lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *info,
671 671 ndr_xa_t *mxa)
672 672 {
673 673 smb_domain_t di;
674 674 int rc;
675 675
676 676 bzero(info, sizeof (struct mslsa_AccountDomainInfo));
677 677
678 678 if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di))
679 679 return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
680 680
681 681 rc = NDR_MSTRING(mxa, di.di_nbname, (ndr_mstring_t *)&info->name);
682 682 info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, di.di_binsid);
683 683
684 684 if ((rc == -1) || (info->sid == NULL))
685 685 return (NT_STATUS_NO_MEMORY);
686 686
687 687 return (NT_STATUS_SUCCESS);
688 688 }
689 689
690 690 /*
691 691 * lsarpc_s_LookupNames
692 692 *
693 693 * This is the service side function for handling name lookup requests.
694 694 * Currently, we only support lookups of a single name. This is also a
695 695 * pass through interface so all we do is act as a proxy between the
696 696 * client and the DC.
697 697 */
698 698 static int
699 699 lsarpc_s_LookupNames(void *arg, ndr_xa_t *mxa)
700 700 {
701 701 struct mslsa_LookupNames *param = arg;
702 702 struct mslsa_rid_entry *rids;
703 703 struct mslsa_domain_table *domain_table;
704 704 struct mslsa_domain_entry *domain_entry;
705 705 smb_account_t account;
706 706 uint32_t status;
707 707 char *accname;
708 708 int rc = 0;
709 709
710 710 if (param->name_table->n_entry != 1)
711 711 return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED);
712 712
713 713 rids = NDR_NEW(mxa, struct mslsa_rid_entry);
714 714 domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
715 715 domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry);
716 716
717 717 if (rids == NULL || domain_table == NULL || domain_entry == NULL) {
718 718 bzero(param, sizeof (struct mslsa_LookupNames));
719 719 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
720 720 return (NDR_DRC_OK);
721 721 }
722 722
723 723 accname = (char *)param->name_table->names->str;
724 724 status = lsa_lookup_name(accname, SidTypeUnknown, &account);
725 725 if (status != NT_STATUS_SUCCESS) {
726 726 bzero(param, sizeof (struct mslsa_LookupNames));
727 727 param->status = NT_SC_ERROR(status);
728 728 return (NDR_DRC_OK);
729 729 }
730 730
731 731 /*
732 732 * Set up the rid table.
733 733 */
734 734 rids[0].sid_name_use = account.a_type;
735 735 rids[0].rid = account.a_rid;
736 736 rids[0].domain_index = 0;
737 737 param->translated_sids.n_entry = 1;
738 738 param->translated_sids.rids = rids;
739 739
740 740 /*
741 741 * Set up the domain table.
742 742 */
743 743 domain_table->entries = domain_entry;
744 744 domain_table->n_entry = 1;
745 745 domain_table->max_n_entry = MLSVC_DOMAIN_MAX;
746 746
747 747 rc = NDR_MSTRING(mxa, account.a_domain,
748 748 (ndr_mstring_t *)&domain_entry->domain_name);
749 749 domain_entry->domain_sid =
750 750 (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid);
751 751
752 752 if (rc == -1 || domain_entry->domain_sid == NULL) {
753 753 smb_account_free(&account);
754 754 bzero(param, sizeof (struct mslsa_LookupNames));
755 755 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
756 756 return (NDR_DRC_OK);
757 757 }
758 758
759 759 param->domain_table = domain_table;
760 760 param->mapped_count = 1;
761 761 param->status = NT_STATUS_SUCCESS;
762 762
763 763 smb_account_free(&account);
764 764 return (NDR_DRC_OK);
765 765 }
766 766
767 767 /*
768 768 * lsarpc_s_LookupSids
769 769 *
770 770 * This is the service side function for handling sid lookup requests.
771 771 * We have to set up both the name table and the domain table in the
772 772 * response. For each SID, we check for UNIX domain (local lookup) or
773 773 * NT domain (DC lookup) and call the appropriate lookup function. This
774 774 * should resolve the SID to a name. Then we need to update the domain
775 775 * table and make the name entry point at the appropriate domain table
776 776 * entry.
777 777 *
778 778 *
779 779 * This RPC should behave as if LookupOptions is LSA_LOOKUP_OPT_ALL and
780 780 * ClientRevision is LSA_CLIENT_REVISION_NT.
781 781 *
782 782 * On success return 0. Otherwise return an RPC specific error code.
783 783 */
784 784
785 785 static int
786 786 lsarpc_s_LookupSids(void *arg, ndr_xa_t *mxa)
787 787 {
788 788 struct mslsa_LookupSids *param = arg;
789 789 struct mslsa_domain_table *domain_table;
790 790 struct mslsa_domain_entry *domain_entry;
791 791 struct mslsa_name_entry *names;
792 792 struct mslsa_name_entry *name;
793 793 smb_account_t account;
794 794 smb_sid_t *sid;
795 795 DWORD n_entry;
796 796 DWORD n_mapped;
797 797 char sidstr[SMB_SID_STRSZ];
798 798 int result;
799 799 int i;
800 800
801 801 bzero(&account, sizeof (smb_account_t));
802 802 n_mapped = 0;
803 803 n_entry = param->lup_sid_table.n_entry;
804 804
805 805 names = NDR_NEWN(mxa, struct mslsa_name_entry, n_entry);
806 806 domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
807 807 domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry,
808 808 MLSVC_DOMAIN_MAX);
809 809
810 810 if (names == NULL || domain_table == NULL || domain_entry == NULL)
811 811 goto lookup_sid_failed;
812 812
813 813 domain_table->entries = domain_entry;
814 814 domain_table->n_entry = 0;
815 815 domain_table->max_n_entry = MLSVC_DOMAIN_MAX;
816 816
817 817 name = names;
818 818 for (i = 0; i < n_entry; ++i, name++) {
819 819 bzero(name, sizeof (struct mslsa_name_entry));
820 820 sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid;
821 821
822 822 result = lsa_lookup_sid(sid, &account);
823 823 if ((result != NT_STATUS_SUCCESS) ||
824 824 (account.a_name == NULL) || (*account.a_name == '\0')) {
825 825 account.a_type = SidTypeUnknown;
826 826 smb_sid_tostr(sid, sidstr);
827 827
828 828 if (NDR_MSTRING(mxa, sidstr,
829 829 (ndr_mstring_t *)&name->name) == -1)
830 830 goto lookup_sid_failed;
831 831
832 832 } else {
833 833 if (NDR_MSTRING(mxa, account.a_name,
834 834 (ndr_mstring_t *)&name->name) == -1)
835 835 goto lookup_sid_failed;
836 836
837 837 ++n_mapped;
838 838 }
839 839
840 840 name->sid_name_use = account.a_type;
841 841
842 842 result = lsarpc_s_UpdateDomainTable(mxa, &account,
843 843 domain_table, &name->domain_ix);
844 844 if (result == -1)
845 845 goto lookup_sid_failed;
846 846
847 847 smb_account_free(&account);
848 848 }
849 849
850 850 param->domain_table = domain_table;
851 851 param->name_table.n_entry = n_entry;
852 852 param->name_table.entries = names;
853 853 param->mapped_count = n_mapped;
854 854
855 855 if (n_mapped == n_entry)
856 856 param->status = NT_STATUS_SUCCESS;
857 857 else if (n_mapped == 0)
858 858 param->status = NT_STATUS_NONE_MAPPED;
859 859 else
860 860 param->status = NT_STATUS_SOME_NOT_MAPPED;
861 861
862 862 return (NDR_DRC_OK);
863 863
864 864 lookup_sid_failed:
865 865 smb_account_free(&account);
866 866 bzero(param, sizeof (struct mslsa_LookupSids));
867 867 return (NDR_DRC_FAULT_OUT_OF_MEMORY);
868 868 }
869 869
870 870 /*
871 871 * lsarpc_s_UpdateDomainTable
872 872 *
873 873 * This routine is responsible for maintaining the domain table which
874 874 * will be returned from a SID lookup. Whenever a name is added to the
875 875 * name table, this function should be called with the corresponding
876 876 * domain name. If the domain information is not already in the table,
877 877 * it is added. On success return 0; Otherwise -1 is returned.
878 878 */
879 879 static int
880 880 lsarpc_s_UpdateDomainTable(ndr_xa_t *mxa,
881 881 smb_account_t *account, struct mslsa_domain_table *domain_table,
882 882 DWORD *domain_idx)
883 883 {
884 884 struct mslsa_domain_entry *dentry;
885 885 DWORD n_entry;
886 886 DWORD i;
887 887 int rc;
888 888
889 889 if (account->a_type == SidTypeUnknown ||
890 890 account->a_type == SidTypeInvalid) {
891 891 /*
892 892 * These types don't need to reference an entry in the
893 893 * domain table. So return -1.
894 894 */
895 895 *domain_idx = (DWORD)-1;
896 896 return (0);
897 897 }
898 898
899 899 if ((dentry = domain_table->entries) == NULL)
900 900 return (-1);
901 901
902 902 if ((n_entry = domain_table->n_entry) >= MLSVC_DOMAIN_MAX)
903 903 return (-1);
904 904
905 905 for (i = 0; i < n_entry; ++i) {
906 906 if (smb_sid_cmp((smb_sid_t *)dentry[i].domain_sid,
907 907 account->a_domsid)) {
908 908 *domain_idx = i;
909 909 return (0);
910 910 }
911 911 }
912 912
913 913 if (i == MLSVC_DOMAIN_MAX)
914 914 return (-1);
915 915
916 916 rc = NDR_MSTRING(mxa, account->a_domain,
917 917 (ndr_mstring_t *)&dentry[i].domain_name);
918 918 dentry[i].domain_sid =
919 919 (struct mslsa_sid *)NDR_SIDDUP(mxa, account->a_domsid);
920 920
921 921 if (rc == -1 || dentry[i].domain_sid == NULL)
922 922 return (-1);
923 923
924 924 ++domain_table->n_entry;
925 925 *domain_idx = i;
926 926 return (0);
927 927 }
928 928
929 929 /*
930 930 * lsarpc_s_LookupSids2
931 931 *
932 932 * Other than the use of lsar_lookup_sids2 and lsar_name_entry2, this
933 933 * is identical to lsarpc_s_LookupSids.
934 934 *
935 935 * Ignore lookup_level, it is reserved and should be zero.
936 936 */
937 937 static int
938 938 lsarpc_s_LookupSids2(void *arg, ndr_xa_t *mxa)
939 939 {
940 940 struct lsar_lookup_sids2 *param = arg;
941 941 struct lsar_name_entry2 *names;
942 942 struct lsar_name_entry2 *name;
943 943 struct mslsa_domain_table *domain_table;
944 944 struct mslsa_domain_entry *domain_entry;
945 945 smb_account_t account;
946 946 smb_sid_t *sid;
947 947 DWORD n_entry;
948 948 DWORD n_mapped;
949 949 char sidstr[SMB_SID_STRSZ];
950 950 int result;
951 951 int i;
952 952
953 953 bzero(&account, sizeof (smb_account_t));
954 954 n_mapped = 0;
955 955 n_entry = param->lup_sid_table.n_entry;
956 956
957 957 names = NDR_NEWN(mxa, struct lsar_name_entry2, n_entry);
958 958 domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
959 959 domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry,
960 960 MLSVC_DOMAIN_MAX);
961 961
962 962 if (names == NULL || domain_table == NULL || domain_entry == NULL)
963 963 goto lookup_sid_failed;
964 964
965 965 domain_table->entries = domain_entry;
966 966 domain_table->n_entry = 0;
967 967 domain_table->max_n_entry = MLSVC_DOMAIN_MAX;
968 968
969 969 name = names;
970 970 for (i = 0; i < n_entry; ++i, name++) {
971 971 bzero(name, sizeof (struct lsar_name_entry2));
972 972 sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid;
973 973
974 974 result = lsa_lookup_sid(sid, &account);
975 975 if ((result != NT_STATUS_SUCCESS) ||
976 976 (account.a_name == NULL) || (*account.a_name == '\0')) {
977 977 account.a_type = SidTypeUnknown;
978 978 smb_sid_tostr(sid, sidstr);
979 979
980 980 if (NDR_MSTRING(mxa, sidstr,
981 981 (ndr_mstring_t *)&name->name) == -1)
982 982 goto lookup_sid_failed;
983 983
984 984 } else {
985 985 if (NDR_MSTRING(mxa, account.a_name,
986 986 (ndr_mstring_t *)&name->name) == -1)
987 987 goto lookup_sid_failed;
988 988
989 989 ++n_mapped;
990 990 }
991 991
992 992 name->sid_name_use = account.a_type;
993 993
994 994 result = lsarpc_s_UpdateDomainTable(mxa, &account,
995 995 domain_table, &name->domain_ix);
996 996 if (result == -1)
997 997 goto lookup_sid_failed;
998 998
999 999 smb_account_free(&account);
1000 1000 }
1001 1001
1002 1002 param->domain_table = domain_table;
1003 1003 param->name_table.n_entry = n_entry;
1004 1004 param->name_table.entries = names;
1005 1005 param->mapped_count = n_mapped;
1006 1006
1007 1007 if (n_mapped == n_entry)
1008 1008 param->status = NT_STATUS_SUCCESS;
1009 1009 else if (n_mapped == 0)
1010 1010 param->status = NT_STATUS_NONE_MAPPED;
1011 1011 else
1012 1012 param->status = NT_STATUS_SOME_NOT_MAPPED;
1013 1013
1014 1014 return (NDR_DRC_OK);
1015 1015
1016 1016 lookup_sid_failed:
1017 1017 smb_account_free(&account);
1018 1018 bzero(param, sizeof (struct lsar_lookup_sids2));
1019 1019 return (NDR_DRC_FAULT_OUT_OF_MEMORY);
1020 1020 }
1021 1021
1022 1022 /*
1023 1023 * LookupSids3 is only valid on domain controllers.
1024 1024 * Other servers must return NT_STATUS_INVALID_SERVER_STATE.
1025 1025 */
1026 1026 /*ARGSUSED*/
1027 1027 static int
1028 1028 lsarpc_s_LookupSids3(void *arg, ndr_xa_t *mxa)
1029 1029 {
1030 1030 struct lsar_lookup_sids3 *param = arg;
1031 1031
1032 1032 bzero(param, sizeof (struct lsar_lookup_sids3));
1033 1033 param->status = NT_SC_ERROR(NT_STATUS_INVALID_SERVER_STATE);
1034 1034 return (NDR_DRC_OK);
1035 1035 }
1036 1036
1037 1037 /*
1038 1038 * lsarpc_s_LookupNames2
1039 1039 *
1040 1040 * Other than the use of lsar_LookupNames2 and lsar_rid_entry2, this
1041 1041 * is identical to lsarpc_s_LookupNames.
1042 1042 *
1043 1043 * If LookupOptions contains LSA_LOOKUP_OPT_LOCAL and LookupLevel is not
1044 1044 * LSA_LOOKUP_WKSTA, return STATUS_INVALID_PARAMETER.
1045 1045 */
1046 1046 static int
1047 1047 lsarpc_s_LookupNames2(void *arg, ndr_xa_t *mxa)
1048 1048 {
1049 1049 struct lsar_LookupNames2 *param = arg;
1050 1050 struct lsar_rid_entry2 *rids;
1051 1051 struct mslsa_domain_table *domain_table;
1052 1052 struct mslsa_domain_entry *domain_entry;
1053 1053 smb_account_t account;
1054 1054 uint32_t status;
1055 1055 char *accname;
1056 1056 int rc = 0;
1057 1057
1058 1058 if (param->name_table->n_entry != 1)
1059 1059 return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED);
1060 1060
1061 1061 if ((param->lookup_options & LSA_LOOKUP_OPT_LOCAL) &&
1062 1062 param->lookup_level != LSA_LOOKUP_WKSTA) {
1063 1063 bzero(param, sizeof (struct lsar_LookupNames2));
1064 1064 param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
1065 1065 return (NDR_DRC_OK);
1066 1066 }
1067 1067
1068 1068 rids = NDR_NEW(mxa, struct lsar_rid_entry2);
1069 1069 domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
1070 1070 domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry);
1071 1071
1072 1072 if (rids == NULL || domain_table == NULL || domain_entry == NULL) {
1073 1073 bzero(param, sizeof (struct lsar_LookupNames2));
1074 1074 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1075 1075 return (NDR_DRC_OK);
1076 1076 }
1077 1077
1078 1078 accname = (char *)param->name_table->names->str;
1079 1079 status = lsa_lookup_name(accname, SidTypeUnknown, &account);
1080 1080 if (status != NT_STATUS_SUCCESS) {
1081 1081 bzero(param, sizeof (struct lsar_LookupNames2));
1082 1082 param->status = NT_SC_ERROR(status);
1083 1083 return (NDR_DRC_OK);
1084 1084 }
1085 1085
1086 1086 /*
1087 1087 * Set up the rid table.
1088 1088 */
1089 1089 bzero(rids, sizeof (struct lsar_rid_entry2));
1090 1090 rids[0].sid_name_use = account.a_type;
1091 1091 rids[0].rid = account.a_rid;
1092 1092 rids[0].domain_index = 0;
1093 1093 param->translated_sids.n_entry = 1;
1094 1094 param->translated_sids.rids = rids;
1095 1095
1096 1096 /*
1097 1097 * Set up the domain table.
1098 1098 */
1099 1099 domain_table->entries = domain_entry;
1100 1100 domain_table->n_entry = 1;
1101 1101 domain_table->max_n_entry = MLSVC_DOMAIN_MAX;
1102 1102
1103 1103 rc = NDR_MSTRING(mxa, account.a_domain,
1104 1104 (ndr_mstring_t *)&domain_entry->domain_name);
1105 1105
1106 1106 domain_entry->domain_sid =
1107 1107 (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid);
1108 1108
1109 1109 if (rc == -1 || domain_entry->domain_sid == NULL) {
1110 1110 smb_account_free(&account);
1111 1111 bzero(param, sizeof (struct lsar_LookupNames2));
1112 1112 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1113 1113 return (NDR_DRC_OK);
1114 1114 }
1115 1115
1116 1116 param->domain_table = domain_table;
1117 1117 param->mapped_count = 1;
1118 1118 param->status = NT_STATUS_SUCCESS;
1119 1119
1120 1120 smb_account_free(&account);
1121 1121 return (NDR_DRC_OK);
1122 1122 }
1123 1123
1124 1124 /*
1125 1125 * Other than the use of lsar_LookupNames2 and lsar_rid_entry2, this
1126 1126 * is identical to lsarpc_s_LookupNames.
1127 1127 *
1128 1128 * If LookupOptions contains LSA_LOOKUP_OPT_LOCAL and LookupLevel is not
1129 1129 * LSA_LOOKUP_WKSTA, return STATUS_INVALID_PARAMETER.
1130 1130 */
1131 1131 static int
1132 1132 lsarpc_s_LookupNames3(void *arg, ndr_xa_t *mxa)
1133 1133 {
1134 1134 struct lsar_LookupNames3 *param = arg;
1135 1135 struct lsar_translated_sid_ex2 *sids;
1136 1136 struct mslsa_domain_table *domain_table;
1137 1137 struct mslsa_domain_entry *domain_entry;
1138 1138 smb_account_t account;
1139 1139 uint32_t status;
1140 1140 char *accname;
1141 1141 int rc = 0;
1142 1142
1143 1143 if (param->name_table->n_entry != 1)
1144 1144 return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED);
1145 1145
1146 1146 if ((param->lookup_options & LSA_LOOKUP_OPT_LOCAL) &&
1147 1147 param->lookup_level != LSA_LOOKUP_WKSTA) {
1148 1148 bzero(param, sizeof (struct lsar_LookupNames3));
1149 1149 param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
1150 1150 return (NDR_DRC_OK);
1151 1151 }
1152 1152
1153 1153 sids = NDR_NEW(mxa, struct lsar_translated_sid_ex2);
1154 1154 domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
1155 1155 domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry);
1156 1156
1157 1157 if (sids == NULL || domain_table == NULL || domain_entry == NULL) {
1158 1158 bzero(param, sizeof (struct lsar_LookupNames3));
1159 1159 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1160 1160 return (NDR_DRC_OK);
1161 1161 }
1162 1162
1163 1163 accname = (char *)param->name_table->names->str;
1164 1164 status = lsa_lookup_name(accname, SidTypeUnknown, &account);
1165 1165 if (status != NT_STATUS_SUCCESS) {
1166 1166 bzero(param, sizeof (struct lsar_LookupNames3));
1167 1167 param->status = NT_SC_ERROR(status);
1168 1168 return (NDR_DRC_OK);
1169 1169 }
1170 1170
1171 1171 /*
1172 1172 * Set up the SID table.
1173 1173 */
1174 1174 bzero(sids, sizeof (struct lsar_translated_sid_ex2));
1175 1175 sids[0].sid_name_use = account.a_type;
1176 1176 sids[0].sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_sid);
1177 1177 sids[0].domain_index = 0;
1178 1178 param->translated_sids.n_entry = 1;
1179 1179 param->translated_sids.sids = sids;
1180 1180
1181 1181 /*
1182 1182 * Set up the domain table.
1183 1183 */
1184 1184 domain_table->entries = domain_entry;
1185 1185 domain_table->n_entry = 1;
1186 1186 domain_table->max_n_entry = MLSVC_DOMAIN_MAX;
1187 1187
1188 1188 rc = NDR_MSTRING(mxa, account.a_domain,
1189 1189 (ndr_mstring_t *)&domain_entry->domain_name);
1190 1190
1191 1191 domain_entry->domain_sid =
1192 1192 (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid);
1193 1193
1194 1194 if (rc == -1 || domain_entry->domain_sid == NULL) {
1195 1195 smb_account_free(&account);
1196 1196 bzero(param, sizeof (struct lsar_LookupNames3));
1197 1197 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1198 1198 return (NDR_DRC_OK);
1199 1199 }
1200 1200
1201 1201 param->domain_table = domain_table;
1202 1202 param->mapped_count = 1;
1203 1203 param->status = NT_STATUS_SUCCESS;
1204 1204
1205 1205 smb_account_free(&account);
1206 1206 return (NDR_DRC_OK);
1207 1207 }
1208 1208
1209 1209 /*
1210 1210 * LookupNames4 is only valid on domain controllers.
1211 1211 * Other servers must return NT_STATUS_INVALID_SERVER_STATE.
1212 1212 */
1213 1213 /*ARGSUSED*/
1214 1214 static int
1215 1215 lsarpc_s_LookupNames4(void *arg, ndr_xa_t *mxa)
1216 1216 {
1217 1217 struct lsar_LookupNames4 *param = arg;
1218 1218
1219 1219 bzero(param, sizeof (struct lsar_LookupNames4));
1220 1220 param->status = NT_SC_ERROR(NT_STATUS_INVALID_SERVER_STATE);
1221 1221 return (NDR_DRC_OK);
1222 1222 }
1223 1223
1224 1224 /*
1225 1225 * There is a bug in the way that ndrgen and the marshalling code handles
1226 1226 * unions so we need to fix some of the data offsets at runtime. The
1227 1227 * following macros and the fixup functions handle the corrections.
1228 1228 */
1229 1229
1230 1230 DECL_FIXUP_STRUCT(mslsa_PolicyInfoResUnion);
1231 1231 DECL_FIXUP_STRUCT(mslsa_PolicyInfoRes);
1232 1232 DECL_FIXUP_STRUCT(mslsa_QueryInfoPolicy);
1233 1233 void
1234 1234 fixup_mslsa_QueryInfoPolicy(struct mslsa_QueryInfoPolicy *val)
1235 1235 {
1236 1236 unsigned short size1 = 0;
1237 1237 unsigned short size2 = 0;
1238 1238 unsigned short size3 = 0;
1239 1239
1240 1240 switch (val->info_class) {
1241 1241 case MSLSA_POLICY_AUDIT_EVENTS_INFO:
1242 1242 size1 = sizeof (struct mslsa_AuditEventsInfo);
1243 1243 break;
1244 1244
1245 1245 case MSLSA_POLICY_PRIMARY_DOMAIN_INFO:
1246 1246 size1 = sizeof (struct mslsa_PrimaryDomainInfo);
1247 1247 break;
1248 1248
1249 1249 case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO:
1250 1250 size1 = sizeof (struct mslsa_AccountDomainInfo);
1251 1251 break;
1252 1252
1253 1253 case MSLSA_POLICY_SERVER_ROLE_INFO:
1254 1254 size1 = sizeof (struct mslsa_ServerRoleInfo);
1255 1255 break;
1256 1256
1257 1257 case MSLSA_POLICY_DNS_DOMAIN_INFO:
1258 1258 size1 = sizeof (struct mslsa_DnsDomainInfo);
1259 1259 break;
1260 1260
1261 1261 default:
1262 1262 return;
1263 1263 };
1264 1264
1265 1265 size2 = size1 + (2 * sizeof (DWORD));
1266 1266 size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
1267 1267
1268 1268 FIXUP_PDU_SIZE(mslsa_PolicyInfoResUnion, size1);
1269 1269 FIXUP_PDU_SIZE(mslsa_PolicyInfoRes, size2);
1270 1270 FIXUP_PDU_SIZE(mslsa_QueryInfoPolicy, size3);
1271 1271 }
↓ open down ↓ |
1224 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX