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 static int 518 lsarpc_s_GetConnectedUser(void *arg, ndr_xa_t *mxa) 519 { 520 struct mslsa_GetConnectedUser *param = arg; 521 smb_netuserinfo_t *user = mxa->pipe->np_user; 522 DWORD status = NT_STATUS_SUCCESS; 523 smb_domainex_t di; 524 int rc1; 525 int rc2; 526 527 if (!smb_domain_getinfo(&di)) { 528 bzero(param, sizeof (struct mslsa_GetConnectedUser)); 529 status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 530 param->status = status; 531 return (NDR_DRC_OK); 532 } 533 534 param->owner = NDR_NEW(mxa, struct mslsa_string_desc); 535 param->domain = NDR_NEW(mxa, struct mslsa_DomainName); 536 if (param->owner == NULL || param->domain == NULL) { 537 status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 538 param->status = status; 539 return (NDR_DRC_OK); 540 } 541 542 param->domain->name = NDR_NEW(mxa, struct mslsa_string_desc); 543 if (param->domain->name == NULL) { 544 status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 545 param->status = status; 546 return (NDR_DRC_OK); 547 } 548 549 rc1 = NDR_MSTRING(mxa, user->ui_account, 550 (ndr_mstring_t *)param->owner); 551 rc2 = NDR_MSTRING(mxa, user->ui_domain, 552 (ndr_mstring_t *)param->domain->name); 553 554 if (rc1 == -1 || rc2 == -1) 555 status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 556 557 param->status = status; 558 return (NDR_DRC_OK); 559 } 560 561 562 /* 563 * lsarpc_s_QueryInfoPolicy 564 * 565 * This is the server side function for handling LSA information policy 566 * queries. Currently, we only support primary domain and account 567 * domain queries. This is just a front end to switch on the request 568 * and hand it off to the appropriate function to actually deal with 569 * obtaining and building the response. 570 */ 571 static int 572 lsarpc_s_QueryInfoPolicy(void *arg, ndr_xa_t *mxa) 573 { 574 struct mslsa_QueryInfoPolicy *param = arg; 575 union mslsa_PolicyInfoResUnion *ru = ¶m->ru; 576 int security_mode; 577 DWORD status; 578 579 param->switch_value = param->info_class; 580 581 switch (param->info_class) { 582 case MSLSA_POLICY_AUDIT_EVENTS_INFO: 583 ru->audit_events.enabled = 0; 584 ru->audit_events.count = 1; 585 ru->audit_events.settings 586 = NDR_MALLOC(mxa, sizeof (DWORD)); 587 bzero(ru->audit_events.settings, sizeof (DWORD)); 588 status = NT_STATUS_SUCCESS; 589 break; 590 591 case MSLSA_POLICY_PRIMARY_DOMAIN_INFO: 592 status = lsarpc_s_PrimaryDomainInfo(&ru->pd_info, mxa); 593 break; 594 595 case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO: 596 status = lsarpc_s_AccountDomainInfo(&ru->ad_info, mxa); 597 break; 598 599 case MSLSA_POLICY_SERVER_ROLE_INFO: 600 security_mode = smb_config_get_secmode(); 601 602 if (security_mode == SMB_SECMODE_DOMAIN) 603 ru->server_role.role = LSA_ROLE_MEMBER_SERVER; 604 else 605 ru->server_role.role = LSA_ROLE_STANDALONE_SERVER; 606 607 ru->server_role.pad = 0; 608 status = NT_STATUS_SUCCESS; 609 break; 610 611 default: 612 bzero(param, sizeof (struct mslsa_QueryInfoPolicy)); 613 param->status = NT_SC_ERROR(NT_STATUS_INVALID_INFO_CLASS); 614 return (NDR_DRC_OK); 615 } 616 617 if (status != NT_STATUS_SUCCESS) 618 param->status = NT_SC_ERROR(status); 619 else 620 param->status = NT_STATUS_SUCCESS; 621 param->address = (DWORD)(uintptr_t)ru; 622 623 return (NDR_DRC_OK); 624 } 625 626 627 /* 628 * lsarpc_s_PrimaryDomainInfo 629 * 630 * Service primary domain policy queries. In domain mode, return the 631 * primary domain name and SID. In workgroup mode, return the local 632 * hostname and local domain SID. 633 * 634 * Note: info is zeroed on entry to ensure the SID and name do not 635 * contain spurious values if an error is returned. 636 */ 637 static DWORD 638 lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *info, 639 ndr_xa_t *mxa) 640 { 641 smb_domain_t di; 642 boolean_t found; 643 int rc; 644 645 bzero(info, sizeof (struct mslsa_PrimaryDomainInfo)); 646 647 if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) 648 found = smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di); 649 else 650 found = smb_domain_lookup_type(SMB_DOMAIN_PRIMARY, &di); 651 652 if (!found) 653 return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 654 655 rc = NDR_MSTRING(mxa, di.di_nbname, (ndr_mstring_t *)&info->name); 656 info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, di.di_binsid); 657 658 if ((rc == -1) || (info->sid == NULL)) 659 return (NT_STATUS_NO_MEMORY); 660 661 return (NT_STATUS_SUCCESS); 662 } 663 664 665 /* 666 * lsarpc_s_AccountDomainInfo 667 * 668 * Service account domain policy queries. We return our local domain 669 * information so that the client knows who to query for information 670 * on local names and SIDs. The domain name is the local hostname. 671 * 672 * Note: info is zeroed on entry to ensure the SID and name do not 673 * contain spurious values if an error is returned. 674 */ 675 static DWORD 676 lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *info, 677 ndr_xa_t *mxa) 678 { 679 smb_domain_t di; 680 int rc; 681 682 bzero(info, sizeof (struct mslsa_AccountDomainInfo)); 683 684 if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) 685 return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 686 687 rc = NDR_MSTRING(mxa, di.di_nbname, (ndr_mstring_t *)&info->name); 688 info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, di.di_binsid); 689 690 if ((rc == -1) || (info->sid == NULL)) 691 return (NT_STATUS_NO_MEMORY); 692 693 return (NT_STATUS_SUCCESS); 694 } 695 696 /* 697 * lsarpc_s_LookupNames 698 * 699 * This is the service side function for handling name lookup requests. 700 * Currently, we only support lookups of a single name. This is also a 701 * pass through interface so all we do is act as a proxy between the 702 * client and the DC. 703 */ 704 static int 705 lsarpc_s_LookupNames(void *arg, ndr_xa_t *mxa) 706 { 707 struct mslsa_LookupNames *param = arg; 708 struct mslsa_rid_entry *rids; 709 struct mslsa_domain_table *domain_table; 710 struct mslsa_domain_entry *domain_entry; 711 smb_account_t account; 712 uint32_t status; 713 char *accname; 714 int rc = 0; 715 716 if (param->name_table->n_entry != 1) 717 return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED); 718 719 rids = NDR_NEW(mxa, struct mslsa_rid_entry); 720 domain_table = NDR_NEW(mxa, struct mslsa_domain_table); 721 domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry); 722 723 if (rids == NULL || domain_table == NULL || domain_entry == NULL) { 724 bzero(param, sizeof (struct mslsa_LookupNames)); 725 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 726 return (NDR_DRC_OK); 727 } 728 729 accname = (char *)param->name_table->names->str; 730 status = lsa_lookup_name(accname, SidTypeUnknown, &account); 731 if (status != NT_STATUS_SUCCESS) { 732 bzero(param, sizeof (struct mslsa_LookupNames)); 733 param->status = NT_SC_ERROR(status); 734 return (NDR_DRC_OK); 735 } 736 737 /* 738 * Set up the rid table. 739 */ 740 rids[0].sid_name_use = account.a_type; 741 rids[0].rid = account.a_rid; 742 rids[0].domain_index = 0; 743 param->translated_sids.n_entry = 1; 744 param->translated_sids.rids = rids; 745 746 /* 747 * Set up the domain table. 748 */ 749 domain_table->entries = domain_entry; 750 domain_table->n_entry = 1; 751 domain_table->max_n_entry = MLSVC_DOMAIN_MAX; 752 753 rc = NDR_MSTRING(mxa, account.a_domain, 754 (ndr_mstring_t *)&domain_entry->domain_name); 755 domain_entry->domain_sid = 756 (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid); 757 758 if (rc == -1 || domain_entry->domain_sid == NULL) { 759 smb_account_free(&account); 760 bzero(param, sizeof (struct mslsa_LookupNames)); 761 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 762 return (NDR_DRC_OK); 763 } 764 765 param->domain_table = domain_table; 766 param->mapped_count = 1; 767 param->status = NT_STATUS_SUCCESS; 768 769 smb_account_free(&account); 770 return (NDR_DRC_OK); 771 } 772 773 /* 774 * lsarpc_s_LookupSids 775 * 776 * This is the service side function for handling sid lookup requests. 777 * We have to set up both the name table and the domain table in the 778 * response. For each SID, we check for UNIX domain (local lookup) or 779 * NT domain (DC lookup) and call the appropriate lookup function. This 780 * should resolve the SID to a name. Then we need to update the domain 781 * table and make the name entry point at the appropriate domain table 782 * entry. 783 * 784 * 785 * This RPC should behave as if LookupOptions is LSA_LOOKUP_OPT_ALL and 786 * ClientRevision is LSA_CLIENT_REVISION_NT. 787 * 788 * On success return 0. Otherwise return an RPC specific error code. 789 */ 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 DWORD n_mapped; 803 char sidstr[SMB_SID_STRSZ]; 804 int result; 805 int i; 806 807 bzero(&account, sizeof (smb_account_t)); 808 n_mapped = 0; 809 n_entry = param->lup_sid_table.n_entry; 810 811 names = NDR_NEWN(mxa, struct mslsa_name_entry, n_entry); 812 domain_table = NDR_NEW(mxa, struct mslsa_domain_table); 813 domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry, 814 MLSVC_DOMAIN_MAX); 815 816 if (names == NULL || domain_table == NULL || domain_entry == NULL) 817 goto lookup_sid_failed; 818 819 domain_table->entries = domain_entry; 820 domain_table->n_entry = 0; 821 domain_table->max_n_entry = MLSVC_DOMAIN_MAX; 822 823 name = names; 824 for (i = 0; i < n_entry; ++i, name++) { 825 bzero(name, sizeof (struct mslsa_name_entry)); 826 sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid; 827 828 result = lsa_lookup_sid(sid, &account); 829 if ((result != NT_STATUS_SUCCESS) || 830 (account.a_name == NULL) || (*account.a_name == '\0')) { 831 account.a_type = SidTypeUnknown; 832 smb_sid_tostr(sid, sidstr); 833 834 if (NDR_MSTRING(mxa, sidstr, 835 (ndr_mstring_t *)&name->name) == -1) 836 goto lookup_sid_failed; 837 838 } else { 839 if (NDR_MSTRING(mxa, account.a_name, 840 (ndr_mstring_t *)&name->name) == -1) 841 goto lookup_sid_failed; 842 843 ++n_mapped; 844 } 845 846 name->sid_name_use = account.a_type; 847 848 result = lsarpc_s_UpdateDomainTable(mxa, &account, 849 domain_table, &name->domain_ix); 850 if (result == -1) 851 goto lookup_sid_failed; 852 853 smb_account_free(&account); 854 } 855 856 param->domain_table = domain_table; 857 param->name_table.n_entry = n_entry; 858 param->name_table.entries = names; 859 param->mapped_count = n_mapped; 860 861 if (n_mapped == n_entry) 862 param->status = NT_STATUS_SUCCESS; 863 else if (n_mapped == 0) 864 param->status = NT_STATUS_NONE_MAPPED; 865 else 866 param->status = NT_STATUS_SOME_NOT_MAPPED; 867 868 return (NDR_DRC_OK); 869 870 lookup_sid_failed: 871 smb_account_free(&account); 872 bzero(param, sizeof (struct mslsa_LookupSids)); 873 return (NDR_DRC_FAULT_OUT_OF_MEMORY); 874 } 875 876 /* 877 * lsarpc_s_UpdateDomainTable 878 * 879 * This routine is responsible for maintaining the domain table which 880 * will be returned from a SID lookup. Whenever a name is added to the 881 * name table, this function should be called with the corresponding 882 * domain name. If the domain information is not already in the table, 883 * it is added. On success return 0; Otherwise -1 is returned. 884 */ 885 static int 886 lsarpc_s_UpdateDomainTable(ndr_xa_t *mxa, 887 smb_account_t *account, struct mslsa_domain_table *domain_table, 888 DWORD *domain_idx) 889 { 890 struct mslsa_domain_entry *dentry; 891 DWORD n_entry; 892 DWORD i; 893 int rc; 894 895 if (account->a_type == SidTypeUnknown || 896 account->a_type == SidTypeInvalid) { 897 /* 898 * These types don't need to reference an entry in the 899 * domain table. So return -1. 900 */ 901 *domain_idx = (DWORD)-1; 902 return (0); 903 } 904 905 if ((dentry = domain_table->entries) == NULL) 906 return (-1); 907 908 if ((n_entry = domain_table->n_entry) >= MLSVC_DOMAIN_MAX) 909 return (-1); 910 911 for (i = 0; i < n_entry; ++i) { 912 if (smb_sid_cmp((smb_sid_t *)dentry[i].domain_sid, 913 account->a_domsid)) { 914 *domain_idx = i; 915 return (0); 916 } 917 } 918 919 if (i == MLSVC_DOMAIN_MAX) 920 return (-1); 921 922 rc = NDR_MSTRING(mxa, account->a_domain, 923 (ndr_mstring_t *)&dentry[i].domain_name); 924 dentry[i].domain_sid = 925 (struct mslsa_sid *)NDR_SIDDUP(mxa, account->a_domsid); 926 927 if (rc == -1 || dentry[i].domain_sid == NULL) 928 return (-1); 929 930 ++domain_table->n_entry; 931 *domain_idx = i; 932 return (0); 933 } 934 935 /* 936 * lsarpc_s_LookupSids2 937 * 938 * Other than the use of lsar_lookup_sids2 and lsar_name_entry2, this 939 * is identical to lsarpc_s_LookupSids. 940 * 941 * Ignore lookup_level, it is reserved and should be zero. 942 */ 943 static int 944 lsarpc_s_LookupSids2(void *arg, ndr_xa_t *mxa) 945 { 946 struct lsar_lookup_sids2 *param = arg; 947 struct lsar_name_entry2 *names; 948 struct lsar_name_entry2 *name; 949 struct mslsa_domain_table *domain_table; 950 struct mslsa_domain_entry *domain_entry; 951 smb_account_t account; 952 smb_sid_t *sid; 953 DWORD n_entry; 954 DWORD n_mapped; 955 char sidstr[SMB_SID_STRSZ]; 956 int result; 957 int i; 958 959 bzero(&account, sizeof (smb_account_t)); 960 n_mapped = 0; 961 n_entry = param->lup_sid_table.n_entry; 962 963 names = NDR_NEWN(mxa, struct lsar_name_entry2, n_entry); 964 domain_table = NDR_NEW(mxa, struct mslsa_domain_table); 965 domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry, 966 MLSVC_DOMAIN_MAX); 967 968 if (names == NULL || domain_table == NULL || domain_entry == NULL) 969 goto lookup_sid_failed; 970 971 domain_table->entries = domain_entry; 972 domain_table->n_entry = 0; 973 domain_table->max_n_entry = MLSVC_DOMAIN_MAX; 974 975 name = names; 976 for (i = 0; i < n_entry; ++i, name++) { 977 bzero(name, sizeof (struct lsar_name_entry2)); 978 sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid; 979 980 result = lsa_lookup_sid(sid, &account); 981 if ((result != NT_STATUS_SUCCESS) || 982 (account.a_name == NULL) || (*account.a_name == '\0')) { 983 account.a_type = SidTypeUnknown; 984 smb_sid_tostr(sid, sidstr); 985 986 if (NDR_MSTRING(mxa, sidstr, 987 (ndr_mstring_t *)&name->name) == -1) 988 goto lookup_sid_failed; 989 990 } else { 991 if (NDR_MSTRING(mxa, account.a_name, 992 (ndr_mstring_t *)&name->name) == -1) 993 goto lookup_sid_failed; 994 995 ++n_mapped; 996 } 997 998 name->sid_name_use = account.a_type; 999 1000 result = lsarpc_s_UpdateDomainTable(mxa, &account, 1001 domain_table, &name->domain_ix); 1002 if (result == -1) 1003 goto lookup_sid_failed; 1004 1005 smb_account_free(&account); 1006 } 1007 1008 param->domain_table = domain_table; 1009 param->name_table.n_entry = n_entry; 1010 param->name_table.entries = names; 1011 param->mapped_count = n_mapped; 1012 1013 if (n_mapped == n_entry) 1014 param->status = NT_STATUS_SUCCESS; 1015 else if (n_mapped == 0) 1016 param->status = NT_STATUS_NONE_MAPPED; 1017 else 1018 param->status = NT_STATUS_SOME_NOT_MAPPED; 1019 1020 return (NDR_DRC_OK); 1021 1022 lookup_sid_failed: 1023 smb_account_free(&account); 1024 bzero(param, sizeof (struct lsar_lookup_sids2)); 1025 return (NDR_DRC_FAULT_OUT_OF_MEMORY); 1026 } 1027 1028 /* 1029 * LookupSids3 is only valid on domain controllers. 1030 * Other servers must return NT_STATUS_INVALID_SERVER_STATE. 1031 */ 1032 /*ARGSUSED*/ 1033 static int 1034 lsarpc_s_LookupSids3(void *arg, ndr_xa_t *mxa) 1035 { 1036 struct lsar_lookup_sids3 *param = arg; 1037 1038 bzero(param, sizeof (struct lsar_lookup_sids3)); 1039 param->status = NT_SC_ERROR(NT_STATUS_INVALID_SERVER_STATE); 1040 return (NDR_DRC_OK); 1041 } 1042 1043 /* 1044 * lsarpc_s_LookupNames2 1045 * 1046 * Other than the use of lsar_LookupNames2 and lsar_rid_entry2, this 1047 * is identical to lsarpc_s_LookupNames. 1048 * 1049 * If LookupOptions contains LSA_LOOKUP_OPT_LOCAL and LookupLevel is not 1050 * LSA_LOOKUP_WKSTA, return STATUS_INVALID_PARAMETER. 1051 */ 1052 static int 1053 lsarpc_s_LookupNames2(void *arg, ndr_xa_t *mxa) 1054 { 1055 struct lsar_LookupNames2 *param = arg; 1056 struct lsar_rid_entry2 *rids; 1057 struct mslsa_domain_table *domain_table; 1058 struct mslsa_domain_entry *domain_entry; 1059 smb_account_t account; 1060 uint32_t status; 1061 char *accname; 1062 int rc = 0; 1063 1064 if (param->name_table->n_entry != 1) 1065 return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED); 1066 1067 if ((param->lookup_options & LSA_LOOKUP_OPT_LOCAL) && 1068 param->lookup_level != LSA_LOOKUP_WKSTA) { 1069 bzero(param, sizeof (struct lsar_LookupNames2)); 1070 param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 1071 return (NDR_DRC_OK); 1072 } 1073 1074 rids = NDR_NEW(mxa, struct lsar_rid_entry2); 1075 domain_table = NDR_NEW(mxa, struct mslsa_domain_table); 1076 domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry); 1077 1078 if (rids == NULL || domain_table == NULL || domain_entry == NULL) { 1079 bzero(param, sizeof (struct lsar_LookupNames2)); 1080 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1081 return (NDR_DRC_OK); 1082 } 1083 1084 accname = (char *)param->name_table->names->str; 1085 status = lsa_lookup_name(accname, SidTypeUnknown, &account); 1086 if (status != NT_STATUS_SUCCESS) { 1087 bzero(param, sizeof (struct lsar_LookupNames2)); 1088 param->status = NT_SC_ERROR(status); 1089 return (NDR_DRC_OK); 1090 } 1091 1092 /* 1093 * Set up the rid table. 1094 */ 1095 bzero(rids, sizeof (struct lsar_rid_entry2)); 1096 rids[0].sid_name_use = account.a_type; 1097 rids[0].rid = account.a_rid; 1098 rids[0].domain_index = 0; 1099 param->translated_sids.n_entry = 1; 1100 param->translated_sids.rids = rids; 1101 1102 /* 1103 * Set up the domain table. 1104 */ 1105 domain_table->entries = domain_entry; 1106 domain_table->n_entry = 1; 1107 domain_table->max_n_entry = MLSVC_DOMAIN_MAX; 1108 1109 rc = NDR_MSTRING(mxa, account.a_domain, 1110 (ndr_mstring_t *)&domain_entry->domain_name); 1111 1112 domain_entry->domain_sid = 1113 (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid); 1114 1115 if (rc == -1 || domain_entry->domain_sid == NULL) { 1116 smb_account_free(&account); 1117 bzero(param, sizeof (struct lsar_LookupNames2)); 1118 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1119 return (NDR_DRC_OK); 1120 } 1121 1122 param->domain_table = domain_table; 1123 param->mapped_count = 1; 1124 param->status = NT_STATUS_SUCCESS; 1125 1126 smb_account_free(&account); 1127 return (NDR_DRC_OK); 1128 } 1129 1130 /* 1131 * Other than the use of lsar_LookupNames2 and lsar_rid_entry2, this 1132 * is identical to lsarpc_s_LookupNames. 1133 * 1134 * If LookupOptions contains LSA_LOOKUP_OPT_LOCAL and LookupLevel is not 1135 * LSA_LOOKUP_WKSTA, return STATUS_INVALID_PARAMETER. 1136 */ 1137 static int 1138 lsarpc_s_LookupNames3(void *arg, ndr_xa_t *mxa) 1139 { 1140 struct lsar_LookupNames3 *param = arg; 1141 struct lsar_translated_sid_ex2 *sids; 1142 struct mslsa_domain_table *domain_table; 1143 struct mslsa_domain_entry *domain_entry; 1144 smb_account_t account; 1145 uint32_t status; 1146 char *accname; 1147 int rc = 0; 1148 1149 if (param->name_table->n_entry != 1) 1150 return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED); 1151 1152 if ((param->lookup_options & LSA_LOOKUP_OPT_LOCAL) && 1153 param->lookup_level != LSA_LOOKUP_WKSTA) { 1154 bzero(param, sizeof (struct lsar_LookupNames3)); 1155 param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 1156 return (NDR_DRC_OK); 1157 } 1158 1159 sids = NDR_NEW(mxa, struct lsar_translated_sid_ex2); 1160 domain_table = NDR_NEW(mxa, struct mslsa_domain_table); 1161 domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry); 1162 1163 if (sids == NULL || domain_table == NULL || domain_entry == NULL) { 1164 bzero(param, sizeof (struct lsar_LookupNames3)); 1165 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1166 return (NDR_DRC_OK); 1167 } 1168 1169 accname = (char *)param->name_table->names->str; 1170 status = lsa_lookup_name(accname, SidTypeUnknown, &account); 1171 if (status != NT_STATUS_SUCCESS) { 1172 bzero(param, sizeof (struct lsar_LookupNames3)); 1173 param->status = NT_SC_ERROR(status); 1174 return (NDR_DRC_OK); 1175 } 1176 1177 /* 1178 * Set up the SID table. 1179 */ 1180 bzero(sids, sizeof (struct lsar_translated_sid_ex2)); 1181 sids[0].sid_name_use = account.a_type; 1182 sids[0].sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_sid); 1183 sids[0].domain_index = 0; 1184 param->translated_sids.n_entry = 1; 1185 param->translated_sids.sids = sids; 1186 1187 /* 1188 * Set up the domain table. 1189 */ 1190 domain_table->entries = domain_entry; 1191 domain_table->n_entry = 1; 1192 domain_table->max_n_entry = MLSVC_DOMAIN_MAX; 1193 1194 rc = NDR_MSTRING(mxa, account.a_domain, 1195 (ndr_mstring_t *)&domain_entry->domain_name); 1196 1197 domain_entry->domain_sid = 1198 (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid); 1199 1200 if (rc == -1 || domain_entry->domain_sid == NULL) { 1201 smb_account_free(&account); 1202 bzero(param, sizeof (struct lsar_LookupNames3)); 1203 param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1204 return (NDR_DRC_OK); 1205 } 1206 1207 param->domain_table = domain_table; 1208 param->mapped_count = 1; 1209 param->status = NT_STATUS_SUCCESS; 1210 1211 smb_account_free(&account); 1212 return (NDR_DRC_OK); 1213 } 1214 1215 /* 1216 * LookupNames4 is only valid on domain controllers. 1217 * Other servers must return NT_STATUS_INVALID_SERVER_STATE. 1218 */ 1219 /*ARGSUSED*/ 1220 static int 1221 lsarpc_s_LookupNames4(void *arg, ndr_xa_t *mxa) 1222 { 1223 struct lsar_LookupNames4 *param = arg; 1224 1225 bzero(param, sizeof (struct lsar_LookupNames4)); 1226 param->status = NT_SC_ERROR(NT_STATUS_INVALID_SERVER_STATE); 1227 return (NDR_DRC_OK); 1228 } 1229 1230 /* 1231 * There is a bug in the way that ndrgen and the marshalling code handles 1232 * unions so we need to fix some of the data offsets at runtime. The 1233 * following macros and the fixup functions handle the corrections. 1234 */ 1235 1236 DECL_FIXUP_STRUCT(mslsa_PolicyInfoResUnion); 1237 DECL_FIXUP_STRUCT(mslsa_PolicyInfoRes); 1238 DECL_FIXUP_STRUCT(mslsa_QueryInfoPolicy); 1239 void 1240 fixup_mslsa_QueryInfoPolicy(struct mslsa_QueryInfoPolicy *val) 1241 { 1242 unsigned short size1 = 0; 1243 unsigned short size2 = 0; 1244 unsigned short size3 = 0; 1245 1246 switch (val->info_class) { 1247 case MSLSA_POLICY_AUDIT_EVENTS_INFO: 1248 size1 = sizeof (struct mslsa_AuditEventsInfo); 1249 break; 1250 1251 case MSLSA_POLICY_PRIMARY_DOMAIN_INFO: 1252 size1 = sizeof (struct mslsa_PrimaryDomainInfo); 1253 break; 1254 1255 case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO: 1256 size1 = sizeof (struct mslsa_AccountDomainInfo); 1257 break; 1258 1259 case MSLSA_POLICY_SERVER_ROLE_INFO: 1260 size1 = sizeof (struct mslsa_ServerRoleInfo); 1261 break; 1262 1263 case MSLSA_POLICY_DNS_DOMAIN_INFO: 1264 size1 = sizeof (struct mslsa_DnsDomainInfo); 1265 break; 1266 1267 default: 1268 return; 1269 }; 1270 1271 size2 = size1 + (2 * sizeof (DWORD)); 1272 size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 1273 1274 FIXUP_PDU_SIZE(mslsa_PolicyInfoResUnion, size1); 1275 FIXUP_PDU_SIZE(mslsa_PolicyInfoRes, size2); 1276 FIXUP_PDU_SIZE(mslsa_QueryInfoPolicy, size3); 1277 } 1278