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