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