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