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