17619SJose.Borrego@Sun.COM /* 27619SJose.Borrego@Sun.COM * CDDL HEADER START 37619SJose.Borrego@Sun.COM * 47619SJose.Borrego@Sun.COM * The contents of this file are subject to the terms of the 57619SJose.Borrego@Sun.COM * Common Development and Distribution License (the "License"). 67619SJose.Borrego@Sun.COM * You may not use this file except in compliance with the License. 77619SJose.Borrego@Sun.COM * 87619SJose.Borrego@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97619SJose.Borrego@Sun.COM * or http://www.opensolaris.org/os/licensing. 107619SJose.Borrego@Sun.COM * See the License for the specific language governing permissions 117619SJose.Borrego@Sun.COM * and limitations under the License. 127619SJose.Borrego@Sun.COM * 137619SJose.Borrego@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 147619SJose.Borrego@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157619SJose.Borrego@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 167619SJose.Borrego@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 177619SJose.Borrego@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 187619SJose.Borrego@Sun.COM * 197619SJose.Borrego@Sun.COM * CDDL HEADER END 207619SJose.Borrego@Sun.COM */ 217619SJose.Borrego@Sun.COM /* 22*10966SJordan.Brown@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237619SJose.Borrego@Sun.COM * Use is subject to license terms. 247619SJose.Borrego@Sun.COM */ 257619SJose.Borrego@Sun.COM 267619SJose.Borrego@Sun.COM /* 277619SJose.Borrego@Sun.COM * Active Directory Setup RPC interface used by Windows 2000. 287619SJose.Borrego@Sun.COM */ 297619SJose.Borrego@Sun.COM 307619SJose.Borrego@Sun.COM #include <synch.h> 317619SJose.Borrego@Sun.COM #include <strings.h> 327619SJose.Borrego@Sun.COM #include <stdlib.h> 337619SJose.Borrego@Sun.COM #include <netdb.h> 347619SJose.Borrego@Sun.COM 357619SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h> 367619SJose.Borrego@Sun.COM #include <smbsrv/libmlrpc.h> 377619SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h> 387619SJose.Borrego@Sun.COM #include <smbsrv/ndl/dssetup.ndl> 397619SJose.Borrego@Sun.COM #include <smbsrv/ntstatus.h> 407619SJose.Borrego@Sun.COM #include <smbsrv/smbinfo.h> 417619SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h> 427619SJose.Borrego@Sun.COM 437619SJose.Borrego@Sun.COM int dssetup_get_domain_info(ds_primary_domain_info_t *); 447619SJose.Borrego@Sun.COM 457619SJose.Borrego@Sun.COM static int dssetup_DsRoleGetPrimaryDomainInfo(void *, ndr_xa_t *); 467619SJose.Borrego@Sun.COM static uint32_t dssetup_member_server(ds_primary_domain_info_t *, ndr_xa_t *); 477619SJose.Borrego@Sun.COM static uint32_t dssetup_standalone_server(ds_primary_domain_info_t *, 487619SJose.Borrego@Sun.COM ndr_xa_t *); 497619SJose.Borrego@Sun.COM 508334SJose.Borrego@Sun.COM static ndr_stub_table_t dssetup_stub_table[] = { 517619SJose.Borrego@Sun.COM { dssetup_DsRoleGetPrimaryDomainInfo, 527619SJose.Borrego@Sun.COM DSSETUP_OPNUM_DsRoleGetPrimaryDomainInfo }, 537619SJose.Borrego@Sun.COM {0} 547619SJose.Borrego@Sun.COM }; 557619SJose.Borrego@Sun.COM 568334SJose.Borrego@Sun.COM static ndr_service_t dssetup_service = { 577619SJose.Borrego@Sun.COM "DSSETUP", /* name */ 587619SJose.Borrego@Sun.COM "Active Directory Setup", /* desc */ 597619SJose.Borrego@Sun.COM "\\lsarpc", /* endpoint */ 607619SJose.Borrego@Sun.COM PIPE_LSASS, /* sec_addr_port */ 618334SJose.Borrego@Sun.COM "3919286a-b10c-11d0-9ba8-00c04fd92ef5", 0, /* abstract */ 628334SJose.Borrego@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 637619SJose.Borrego@Sun.COM 0, /* no bind_instance_size */ 647619SJose.Borrego@Sun.COM 0, /* no bind_req() */ 657619SJose.Borrego@Sun.COM 0, /* no unbind_and_close() */ 667619SJose.Borrego@Sun.COM 0, /* use generic_call_stub() */ 677619SJose.Borrego@Sun.COM &TYPEINFO(dssetup_interface), /* interface ti */ 687619SJose.Borrego@Sun.COM dssetup_stub_table /* stub_table */ 697619SJose.Borrego@Sun.COM }; 707619SJose.Borrego@Sun.COM 717619SJose.Borrego@Sun.COM static ds_primary_domain_info_t ds_info; 727619SJose.Borrego@Sun.COM static mutex_t ds_info_mtx; 737619SJose.Borrego@Sun.COM 747619SJose.Borrego@Sun.COM /* 757619SJose.Borrego@Sun.COM * dssetup_initialize 767619SJose.Borrego@Sun.COM * 777619SJose.Borrego@Sun.COM * This function registers the DSSETUP interface with the RPC runtime 787619SJose.Borrego@Sun.COM * library. It must be called in order to use either the client side 797619SJose.Borrego@Sun.COM * or the server side functions. 807619SJose.Borrego@Sun.COM */ 817619SJose.Borrego@Sun.COM void 827619SJose.Borrego@Sun.COM dssetup_initialize(void) 837619SJose.Borrego@Sun.COM { 847619SJose.Borrego@Sun.COM dssetup_clear_domain_info(); 858334SJose.Borrego@Sun.COM (void) ndr_svc_register(&dssetup_service); 867619SJose.Borrego@Sun.COM } 877619SJose.Borrego@Sun.COM 887619SJose.Borrego@Sun.COM void 897619SJose.Borrego@Sun.COM dssetup_clear_domain_info(void) 907619SJose.Borrego@Sun.COM { 917619SJose.Borrego@Sun.COM (void) mutex_lock(&ds_info_mtx); 927619SJose.Borrego@Sun.COM 937619SJose.Borrego@Sun.COM free(ds_info.nt_domain); 947619SJose.Borrego@Sun.COM free(ds_info.dns_domain); 957619SJose.Borrego@Sun.COM free(ds_info.forest); 967619SJose.Borrego@Sun.COM bzero(&ds_info, sizeof (ds_primary_domain_info_t)); 977619SJose.Borrego@Sun.COM 987619SJose.Borrego@Sun.COM (void) mutex_unlock(&ds_info_mtx); 997619SJose.Borrego@Sun.COM } 1007619SJose.Borrego@Sun.COM 1017619SJose.Borrego@Sun.COM /* 1027619SJose.Borrego@Sun.COM * Request for machine role and primary domain information. 1037619SJose.Borrego@Sun.COM */ 1047619SJose.Borrego@Sun.COM static int 1057619SJose.Borrego@Sun.COM dssetup_DsRoleGetPrimaryDomainInfo(void *arg, ndr_xa_t *mxa) 1067619SJose.Borrego@Sun.COM { 1077619SJose.Borrego@Sun.COM dssetup_DsRoleGetPrimaryDomainInfo_t *param = arg; 1087619SJose.Borrego@Sun.COM dssetup_GetPrimaryDomainInfo_t *info; 1097619SJose.Borrego@Sun.COM ds_primary_domain_info_t *info1; 1107619SJose.Borrego@Sun.COM uint32_t status; 1117619SJose.Borrego@Sun.COM int security_mode; 1127619SJose.Borrego@Sun.COM 1138334SJose.Borrego@Sun.COM info = NDR_MALLOC(mxa, sizeof (dssetup_GetPrimaryDomainInfo_t)); 1147619SJose.Borrego@Sun.COM if (info == NULL) { 1157619SJose.Borrego@Sun.COM status = NT_STATUS_NO_MEMORY; 1167619SJose.Borrego@Sun.COM } else if (param->level != DS_ROLE_BASIC_INFORMATION) { 1177619SJose.Borrego@Sun.COM status = NT_STATUS_INVALID_LEVEL; 1187619SJose.Borrego@Sun.COM } else { 1197619SJose.Borrego@Sun.COM info->switch_value = param->level; 1207619SJose.Borrego@Sun.COM info1 = &info->ru.info1; 1217619SJose.Borrego@Sun.COM 1227619SJose.Borrego@Sun.COM security_mode = smb_config_get_secmode(); 1237619SJose.Borrego@Sun.COM 1247619SJose.Borrego@Sun.COM if (security_mode == SMB_SECMODE_DOMAIN) 1257619SJose.Borrego@Sun.COM status = dssetup_member_server(info1, mxa); 1267619SJose.Borrego@Sun.COM else 1277619SJose.Borrego@Sun.COM status = dssetup_standalone_server(info1, mxa); 1287619SJose.Borrego@Sun.COM } 1297619SJose.Borrego@Sun.COM 1307619SJose.Borrego@Sun.COM if (status != NT_STATUS_SUCCESS) { 1317619SJose.Borrego@Sun.COM bzero(param, sizeof (dssetup_DsRoleGetPrimaryDomainInfo_t)); 1327619SJose.Borrego@Sun.COM param->status = NT_SC_ERROR(status); 1337619SJose.Borrego@Sun.COM } else { 1347619SJose.Borrego@Sun.COM param->info = info; 1357619SJose.Borrego@Sun.COM param->status = NT_STATUS_SUCCESS; 1367619SJose.Borrego@Sun.COM } 1377619SJose.Borrego@Sun.COM 1388334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 1397619SJose.Borrego@Sun.COM } 1407619SJose.Borrego@Sun.COM 1417619SJose.Borrego@Sun.COM /* 1427619SJose.Borrego@Sun.COM * When the machine role is domain member: 1437619SJose.Borrego@Sun.COM * nt_domain must contain the NetBIOS domain name 1447619SJose.Borrego@Sun.COM * dns_domain must contain the DNS domain name (cannot be NULL) 1457619SJose.Borrego@Sun.COM * forest must contain the forest name (cannot be NULL) 1467619SJose.Borrego@Sun.COM * 1477619SJose.Borrego@Sun.COM * If DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT is set in flags, the domain_guid 1487619SJose.Borrego@Sun.COM * must contain the domain UUID. Otherwise domain_guid is ignored. 1497619SJose.Borrego@Sun.COM */ 1507619SJose.Borrego@Sun.COM static uint32_t 1517619SJose.Borrego@Sun.COM dssetup_member_server(ds_primary_domain_info_t *info, ndr_xa_t *mxa) 1527619SJose.Borrego@Sun.COM { 1537619SJose.Borrego@Sun.COM char dns_domain[MAXHOSTNAMELEN]; 1547619SJose.Borrego@Sun.COM char nt_domain[MAXHOSTNAMELEN]; 1557619SJose.Borrego@Sun.COM 1567619SJose.Borrego@Sun.COM (void) mutex_lock(&ds_info_mtx); 1577619SJose.Borrego@Sun.COM 1587619SJose.Borrego@Sun.COM if ((ds_info.flags & DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT) == 0) { 1597619SJose.Borrego@Sun.COM /* 1607619SJose.Borrego@Sun.COM * If we don't have the domain GUID, try to get it from a 1617619SJose.Borrego@Sun.COM * domain controller. Otherwise, use local configuration. 1627619SJose.Borrego@Sun.COM */ 1637619SJose.Borrego@Sun.COM free(ds_info.nt_domain); 1647619SJose.Borrego@Sun.COM free(ds_info.dns_domain); 1657619SJose.Borrego@Sun.COM free(ds_info.forest); 1667619SJose.Borrego@Sun.COM (void) dssetup_get_domain_info(&ds_info); 1677619SJose.Borrego@Sun.COM } 1687619SJose.Borrego@Sun.COM 1697619SJose.Borrego@Sun.COM if (ds_info.flags & DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT) { 1707619SJose.Borrego@Sun.COM info->flags = DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT; 1718334SJose.Borrego@Sun.COM info->nt_domain = NDR_STRDUP(mxa, (char *)ds_info.nt_domain); 1728334SJose.Borrego@Sun.COM info->dns_domain = NDR_STRDUP(mxa, (char *)ds_info.dns_domain); 1738334SJose.Borrego@Sun.COM info->forest = NDR_STRDUP(mxa, (char *)ds_info.forest); 1747619SJose.Borrego@Sun.COM bcopy(&ds_info.domain_guid, &info->domain_guid, 1757619SJose.Borrego@Sun.COM sizeof (ndr_uuid_t)); 1767619SJose.Borrego@Sun.COM } else { 1777619SJose.Borrego@Sun.COM if (smb_getdomainname(nt_domain, MAXHOSTNAMELEN) != 0) { 1787619SJose.Borrego@Sun.COM (void) mutex_unlock(&ds_info_mtx); 1797619SJose.Borrego@Sun.COM return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 1807619SJose.Borrego@Sun.COM } 1817619SJose.Borrego@Sun.COM 1827619SJose.Borrego@Sun.COM if (smb_getfqdomainname(dns_domain, MAXHOSTNAMELEN) != 0) { 1837619SJose.Borrego@Sun.COM (void) mutex_unlock(&ds_info_mtx); 1847619SJose.Borrego@Sun.COM return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 1857619SJose.Borrego@Sun.COM } 1867619SJose.Borrego@Sun.COM 187*10966SJordan.Brown@Sun.COM (void) smb_strlwr(dns_domain); 1887619SJose.Borrego@Sun.COM 1897619SJose.Borrego@Sun.COM info->flags = 0; 1908334SJose.Borrego@Sun.COM info->nt_domain = NDR_STRDUP(mxa, nt_domain); 1918334SJose.Borrego@Sun.COM info->dns_domain = NDR_STRDUP(mxa, dns_domain); 1928334SJose.Borrego@Sun.COM info->forest = NDR_STRDUP(mxa, dns_domain); 1937619SJose.Borrego@Sun.COM bzero(&info->domain_guid, sizeof (ndr_uuid_t)); 1947619SJose.Borrego@Sun.COM } 1957619SJose.Borrego@Sun.COM 1967619SJose.Borrego@Sun.COM (void) mutex_unlock(&ds_info_mtx); 1977619SJose.Borrego@Sun.COM 1987619SJose.Borrego@Sun.COM if (info->nt_domain == NULL || 1997619SJose.Borrego@Sun.COM info->dns_domain == NULL || 2007619SJose.Borrego@Sun.COM info->forest == NULL) 2017619SJose.Borrego@Sun.COM return (NT_STATUS_NO_MEMORY); 2027619SJose.Borrego@Sun.COM 2037619SJose.Borrego@Sun.COM info->role = DS_ROLE_MEMBER_SERVER; 2047619SJose.Borrego@Sun.COM return (NT_STATUS_SUCCESS); 2057619SJose.Borrego@Sun.COM } 2067619SJose.Borrego@Sun.COM 2077619SJose.Borrego@Sun.COM /* 2087619SJose.Borrego@Sun.COM * When the machine role is standalone: 2097619SJose.Borrego@Sun.COM * nt_domain must contain the NetBIOS workgroup name 2107619SJose.Borrego@Sun.COM * dns_domain must be NULL 2117619SJose.Borrego@Sun.COM * forest must be NULL 2127619SJose.Borrego@Sun.COM * 2137619SJose.Borrego@Sun.COM * We don't maintain a domain GUID. When DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT 2147619SJose.Borrego@Sun.COM * is not set in flags, domain_guid is ignored. 2157619SJose.Borrego@Sun.COM */ 2167619SJose.Borrego@Sun.COM static uint32_t 2177619SJose.Borrego@Sun.COM dssetup_standalone_server(ds_primary_domain_info_t *info, ndr_xa_t *mxa) 2187619SJose.Borrego@Sun.COM { 2197619SJose.Borrego@Sun.COM char nt_domain[MAXHOSTNAMELEN]; 2207619SJose.Borrego@Sun.COM 2217619SJose.Borrego@Sun.COM if (smb_getdomainname(nt_domain, MAXHOSTNAMELEN) != 0) 2227619SJose.Borrego@Sun.COM return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 2237619SJose.Borrego@Sun.COM 2248334SJose.Borrego@Sun.COM info->nt_domain = NDR_STRDUP(mxa, nt_domain); 2257619SJose.Borrego@Sun.COM if (info->nt_domain == NULL) 2267619SJose.Borrego@Sun.COM return (NT_STATUS_NO_MEMORY); 2277619SJose.Borrego@Sun.COM 2287619SJose.Borrego@Sun.COM info->role = DS_ROLE_STANDALONE_SERVER; 2297619SJose.Borrego@Sun.COM info->flags = 0; 2307619SJose.Borrego@Sun.COM info->dns_domain = NULL; 2317619SJose.Borrego@Sun.COM info->forest = NULL; 2327619SJose.Borrego@Sun.COM bzero(&info->domain_guid, sizeof (ndr_uuid_t)); 2337619SJose.Borrego@Sun.COM return (NT_STATUS_SUCCESS); 2347619SJose.Borrego@Sun.COM } 235