1*7619SJose.Borrego@Sun.COM /* 2*7619SJose.Borrego@Sun.COM * CDDL HEADER START 3*7619SJose.Borrego@Sun.COM * 4*7619SJose.Borrego@Sun.COM * The contents of this file are subject to the terms of the 5*7619SJose.Borrego@Sun.COM * Common Development and Distribution License (the "License"). 6*7619SJose.Borrego@Sun.COM * You may not use this file except in compliance with the License. 7*7619SJose.Borrego@Sun.COM * 8*7619SJose.Borrego@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*7619SJose.Borrego@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*7619SJose.Borrego@Sun.COM * See the License for the specific language governing permissions 11*7619SJose.Borrego@Sun.COM * and limitations under the License. 12*7619SJose.Borrego@Sun.COM * 13*7619SJose.Borrego@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*7619SJose.Borrego@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*7619SJose.Borrego@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*7619SJose.Borrego@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*7619SJose.Borrego@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*7619SJose.Borrego@Sun.COM * 19*7619SJose.Borrego@Sun.COM * CDDL HEADER END 20*7619SJose.Borrego@Sun.COM */ 21*7619SJose.Borrego@Sun.COM /* 22*7619SJose.Borrego@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*7619SJose.Borrego@Sun.COM * Use is subject to license terms. 24*7619SJose.Borrego@Sun.COM */ 25*7619SJose.Borrego@Sun.COM 26*7619SJose.Borrego@Sun.COM /* 27*7619SJose.Borrego@Sun.COM * Active Directory Setup RPC interface used by Windows 2000. 28*7619SJose.Borrego@Sun.COM */ 29*7619SJose.Borrego@Sun.COM 30*7619SJose.Borrego@Sun.COM #include <synch.h> 31*7619SJose.Borrego@Sun.COM #include <strings.h> 32*7619SJose.Borrego@Sun.COM #include <stdlib.h> 33*7619SJose.Borrego@Sun.COM #include <netdb.h> 34*7619SJose.Borrego@Sun.COM 35*7619SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h> 36*7619SJose.Borrego@Sun.COM #include <smbsrv/libmlrpc.h> 37*7619SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h> 38*7619SJose.Borrego@Sun.COM #include <smbsrv/mlsvc_util.h> 39*7619SJose.Borrego@Sun.COM #include <smbsrv/ndl/dssetup.ndl> 40*7619SJose.Borrego@Sun.COM #include <smbsrv/ntstatus.h> 41*7619SJose.Borrego@Sun.COM #include <smbsrv/smbinfo.h> 42*7619SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h> 43*7619SJose.Borrego@Sun.COM 44*7619SJose.Borrego@Sun.COM int dssetup_get_domain_info(ds_primary_domain_info_t *); 45*7619SJose.Borrego@Sun.COM 46*7619SJose.Borrego@Sun.COM static int dssetup_DsRoleGetPrimaryDomainInfo(void *, ndr_xa_t *); 47*7619SJose.Borrego@Sun.COM static uint32_t dssetup_member_server(ds_primary_domain_info_t *, ndr_xa_t *); 48*7619SJose.Borrego@Sun.COM static uint32_t dssetup_standalone_server(ds_primary_domain_info_t *, 49*7619SJose.Borrego@Sun.COM ndr_xa_t *); 50*7619SJose.Borrego@Sun.COM 51*7619SJose.Borrego@Sun.COM static mlrpc_stub_table_t dssetup_stub_table[] = { 52*7619SJose.Borrego@Sun.COM { dssetup_DsRoleGetPrimaryDomainInfo, 53*7619SJose.Borrego@Sun.COM DSSETUP_OPNUM_DsRoleGetPrimaryDomainInfo }, 54*7619SJose.Borrego@Sun.COM {0} 55*7619SJose.Borrego@Sun.COM }; 56*7619SJose.Borrego@Sun.COM 57*7619SJose.Borrego@Sun.COM static mlrpc_service_t dssetup_service = { 58*7619SJose.Borrego@Sun.COM "DSSETUP", /* name */ 59*7619SJose.Borrego@Sun.COM "Active Directory Setup", /* desc */ 60*7619SJose.Borrego@Sun.COM "\\lsarpc", /* endpoint */ 61*7619SJose.Borrego@Sun.COM PIPE_LSASS, /* sec_addr_port */ 62*7619SJose.Borrego@Sun.COM "3919286a-b10c-11d0-9ba800c04fd92ef5", 0, /* abstract */ 63*7619SJose.Borrego@Sun.COM "8a885d04-1ceb-11c9-9fe808002b104860", 2, /* transfer */ 64*7619SJose.Borrego@Sun.COM 0, /* no bind_instance_size */ 65*7619SJose.Borrego@Sun.COM 0, /* no bind_req() */ 66*7619SJose.Borrego@Sun.COM 0, /* no unbind_and_close() */ 67*7619SJose.Borrego@Sun.COM 0, /* use generic_call_stub() */ 68*7619SJose.Borrego@Sun.COM &TYPEINFO(dssetup_interface), /* interface ti */ 69*7619SJose.Borrego@Sun.COM dssetup_stub_table /* stub_table */ 70*7619SJose.Borrego@Sun.COM }; 71*7619SJose.Borrego@Sun.COM 72*7619SJose.Borrego@Sun.COM static ds_primary_domain_info_t ds_info; 73*7619SJose.Borrego@Sun.COM static mutex_t ds_info_mtx; 74*7619SJose.Borrego@Sun.COM 75*7619SJose.Borrego@Sun.COM /* 76*7619SJose.Borrego@Sun.COM * dssetup_initialize 77*7619SJose.Borrego@Sun.COM * 78*7619SJose.Borrego@Sun.COM * This function registers the DSSETUP interface with the RPC runtime 79*7619SJose.Borrego@Sun.COM * library. It must be called in order to use either the client side 80*7619SJose.Borrego@Sun.COM * or the server side functions. 81*7619SJose.Borrego@Sun.COM */ 82*7619SJose.Borrego@Sun.COM void 83*7619SJose.Borrego@Sun.COM dssetup_initialize(void) 84*7619SJose.Borrego@Sun.COM { 85*7619SJose.Borrego@Sun.COM dssetup_clear_domain_info(); 86*7619SJose.Borrego@Sun.COM (void) mlrpc_register_service(&dssetup_service); 87*7619SJose.Borrego@Sun.COM } 88*7619SJose.Borrego@Sun.COM 89*7619SJose.Borrego@Sun.COM void 90*7619SJose.Borrego@Sun.COM dssetup_clear_domain_info(void) 91*7619SJose.Borrego@Sun.COM { 92*7619SJose.Borrego@Sun.COM (void) mutex_lock(&ds_info_mtx); 93*7619SJose.Borrego@Sun.COM 94*7619SJose.Borrego@Sun.COM free(ds_info.nt_domain); 95*7619SJose.Borrego@Sun.COM free(ds_info.dns_domain); 96*7619SJose.Borrego@Sun.COM free(ds_info.forest); 97*7619SJose.Borrego@Sun.COM bzero(&ds_info, sizeof (ds_primary_domain_info_t)); 98*7619SJose.Borrego@Sun.COM 99*7619SJose.Borrego@Sun.COM (void) mutex_unlock(&ds_info_mtx); 100*7619SJose.Borrego@Sun.COM } 101*7619SJose.Borrego@Sun.COM 102*7619SJose.Borrego@Sun.COM /* 103*7619SJose.Borrego@Sun.COM * Request for machine role and primary domain information. 104*7619SJose.Borrego@Sun.COM */ 105*7619SJose.Borrego@Sun.COM static int 106*7619SJose.Borrego@Sun.COM dssetup_DsRoleGetPrimaryDomainInfo(void *arg, ndr_xa_t *mxa) 107*7619SJose.Borrego@Sun.COM { 108*7619SJose.Borrego@Sun.COM dssetup_DsRoleGetPrimaryDomainInfo_t *param = arg; 109*7619SJose.Borrego@Sun.COM dssetup_GetPrimaryDomainInfo_t *info; 110*7619SJose.Borrego@Sun.COM ds_primary_domain_info_t *info1; 111*7619SJose.Borrego@Sun.COM uint32_t status; 112*7619SJose.Borrego@Sun.COM int security_mode; 113*7619SJose.Borrego@Sun.COM 114*7619SJose.Borrego@Sun.COM info = MLRPC_HEAP_MALLOC(mxa, sizeof (dssetup_GetPrimaryDomainInfo_t)); 115*7619SJose.Borrego@Sun.COM if (info == NULL) { 116*7619SJose.Borrego@Sun.COM status = NT_STATUS_NO_MEMORY; 117*7619SJose.Borrego@Sun.COM } else if (param->level != DS_ROLE_BASIC_INFORMATION) { 118*7619SJose.Borrego@Sun.COM status = NT_STATUS_INVALID_LEVEL; 119*7619SJose.Borrego@Sun.COM } else { 120*7619SJose.Borrego@Sun.COM info->switch_value = param->level; 121*7619SJose.Borrego@Sun.COM info1 = &info->ru.info1; 122*7619SJose.Borrego@Sun.COM 123*7619SJose.Borrego@Sun.COM security_mode = smb_config_get_secmode(); 124*7619SJose.Borrego@Sun.COM 125*7619SJose.Borrego@Sun.COM if (security_mode == SMB_SECMODE_DOMAIN) 126*7619SJose.Borrego@Sun.COM status = dssetup_member_server(info1, mxa); 127*7619SJose.Borrego@Sun.COM else 128*7619SJose.Borrego@Sun.COM status = dssetup_standalone_server(info1, mxa); 129*7619SJose.Borrego@Sun.COM } 130*7619SJose.Borrego@Sun.COM 131*7619SJose.Borrego@Sun.COM if (status != NT_STATUS_SUCCESS) { 132*7619SJose.Borrego@Sun.COM bzero(param, sizeof (dssetup_DsRoleGetPrimaryDomainInfo_t)); 133*7619SJose.Borrego@Sun.COM param->status = NT_SC_ERROR(status); 134*7619SJose.Borrego@Sun.COM } else { 135*7619SJose.Borrego@Sun.COM param->info = info; 136*7619SJose.Borrego@Sun.COM param->status = NT_STATUS_SUCCESS; 137*7619SJose.Borrego@Sun.COM } 138*7619SJose.Borrego@Sun.COM 139*7619SJose.Borrego@Sun.COM return (MLRPC_DRC_OK); 140*7619SJose.Borrego@Sun.COM } 141*7619SJose.Borrego@Sun.COM 142*7619SJose.Borrego@Sun.COM /* 143*7619SJose.Borrego@Sun.COM * When the machine role is domain member: 144*7619SJose.Borrego@Sun.COM * nt_domain must contain the NetBIOS domain name 145*7619SJose.Borrego@Sun.COM * dns_domain must contain the DNS domain name (cannot be NULL) 146*7619SJose.Borrego@Sun.COM * forest must contain the forest name (cannot be NULL) 147*7619SJose.Borrego@Sun.COM * 148*7619SJose.Borrego@Sun.COM * If DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT is set in flags, the domain_guid 149*7619SJose.Borrego@Sun.COM * must contain the domain UUID. Otherwise domain_guid is ignored. 150*7619SJose.Borrego@Sun.COM */ 151*7619SJose.Borrego@Sun.COM static uint32_t 152*7619SJose.Borrego@Sun.COM dssetup_member_server(ds_primary_domain_info_t *info, ndr_xa_t *mxa) 153*7619SJose.Borrego@Sun.COM { 154*7619SJose.Borrego@Sun.COM char dns_domain[MAXHOSTNAMELEN]; 155*7619SJose.Borrego@Sun.COM char nt_domain[MAXHOSTNAMELEN]; 156*7619SJose.Borrego@Sun.COM 157*7619SJose.Borrego@Sun.COM (void) mutex_lock(&ds_info_mtx); 158*7619SJose.Borrego@Sun.COM 159*7619SJose.Borrego@Sun.COM if ((ds_info.flags & DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT) == 0) { 160*7619SJose.Borrego@Sun.COM /* 161*7619SJose.Borrego@Sun.COM * If we don't have the domain GUID, try to get it from a 162*7619SJose.Borrego@Sun.COM * domain controller. Otherwise, use local configuration. 163*7619SJose.Borrego@Sun.COM */ 164*7619SJose.Borrego@Sun.COM free(ds_info.nt_domain); 165*7619SJose.Borrego@Sun.COM free(ds_info.dns_domain); 166*7619SJose.Borrego@Sun.COM free(ds_info.forest); 167*7619SJose.Borrego@Sun.COM (void) dssetup_get_domain_info(&ds_info); 168*7619SJose.Borrego@Sun.COM } 169*7619SJose.Borrego@Sun.COM 170*7619SJose.Borrego@Sun.COM if (ds_info.flags & DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT) { 171*7619SJose.Borrego@Sun.COM info->flags = DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT; 172*7619SJose.Borrego@Sun.COM info->nt_domain = MLRPC_HEAP_STRSAVE(mxa, 173*7619SJose.Borrego@Sun.COM (char *)ds_info.nt_domain); 174*7619SJose.Borrego@Sun.COM info->dns_domain = MLRPC_HEAP_STRSAVE(mxa, 175*7619SJose.Borrego@Sun.COM (char *)ds_info.dns_domain); 176*7619SJose.Borrego@Sun.COM info->forest = MLRPC_HEAP_STRSAVE(mxa, (char *)ds_info.forest); 177*7619SJose.Borrego@Sun.COM bcopy(&ds_info.domain_guid, &info->domain_guid, 178*7619SJose.Borrego@Sun.COM sizeof (ndr_uuid_t)); 179*7619SJose.Borrego@Sun.COM } else { 180*7619SJose.Borrego@Sun.COM if (smb_getdomainname(nt_domain, MAXHOSTNAMELEN) != 0) { 181*7619SJose.Borrego@Sun.COM (void) mutex_unlock(&ds_info_mtx); 182*7619SJose.Borrego@Sun.COM return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 183*7619SJose.Borrego@Sun.COM } 184*7619SJose.Borrego@Sun.COM 185*7619SJose.Borrego@Sun.COM if (smb_getfqdomainname(dns_domain, MAXHOSTNAMELEN) != 0) { 186*7619SJose.Borrego@Sun.COM (void) mutex_unlock(&ds_info_mtx); 187*7619SJose.Borrego@Sun.COM return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 188*7619SJose.Borrego@Sun.COM } 189*7619SJose.Borrego@Sun.COM 190*7619SJose.Borrego@Sun.COM (void) utf8_strlwr(dns_domain); 191*7619SJose.Borrego@Sun.COM 192*7619SJose.Borrego@Sun.COM info->flags = 0; 193*7619SJose.Borrego@Sun.COM info->nt_domain = MLRPC_HEAP_STRSAVE(mxa, nt_domain); 194*7619SJose.Borrego@Sun.COM info->dns_domain = MLRPC_HEAP_STRSAVE(mxa, dns_domain); 195*7619SJose.Borrego@Sun.COM info->forest = MLRPC_HEAP_STRSAVE(mxa, dns_domain); 196*7619SJose.Borrego@Sun.COM bzero(&info->domain_guid, sizeof (ndr_uuid_t)); 197*7619SJose.Borrego@Sun.COM } 198*7619SJose.Borrego@Sun.COM 199*7619SJose.Borrego@Sun.COM (void) mutex_unlock(&ds_info_mtx); 200*7619SJose.Borrego@Sun.COM 201*7619SJose.Borrego@Sun.COM if (info->nt_domain == NULL || 202*7619SJose.Borrego@Sun.COM info->dns_domain == NULL || 203*7619SJose.Borrego@Sun.COM info->forest == NULL) 204*7619SJose.Borrego@Sun.COM return (NT_STATUS_NO_MEMORY); 205*7619SJose.Borrego@Sun.COM 206*7619SJose.Borrego@Sun.COM info->role = DS_ROLE_MEMBER_SERVER; 207*7619SJose.Borrego@Sun.COM return (NT_STATUS_SUCCESS); 208*7619SJose.Borrego@Sun.COM } 209*7619SJose.Borrego@Sun.COM 210*7619SJose.Borrego@Sun.COM /* 211*7619SJose.Borrego@Sun.COM * When the machine role is standalone: 212*7619SJose.Borrego@Sun.COM * nt_domain must contain the NetBIOS workgroup name 213*7619SJose.Borrego@Sun.COM * dns_domain must be NULL 214*7619SJose.Borrego@Sun.COM * forest must be NULL 215*7619SJose.Borrego@Sun.COM * 216*7619SJose.Borrego@Sun.COM * We don't maintain a domain GUID. When DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT 217*7619SJose.Borrego@Sun.COM * is not set in flags, domain_guid is ignored. 218*7619SJose.Borrego@Sun.COM */ 219*7619SJose.Borrego@Sun.COM static uint32_t 220*7619SJose.Borrego@Sun.COM dssetup_standalone_server(ds_primary_domain_info_t *info, ndr_xa_t *mxa) 221*7619SJose.Borrego@Sun.COM { 222*7619SJose.Borrego@Sun.COM char nt_domain[MAXHOSTNAMELEN]; 223*7619SJose.Borrego@Sun.COM 224*7619SJose.Borrego@Sun.COM if (smb_getdomainname(nt_domain, MAXHOSTNAMELEN) != 0) 225*7619SJose.Borrego@Sun.COM return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 226*7619SJose.Borrego@Sun.COM 227*7619SJose.Borrego@Sun.COM info->nt_domain = MLRPC_HEAP_STRSAVE(mxa, nt_domain); 228*7619SJose.Borrego@Sun.COM if (info->nt_domain == NULL) 229*7619SJose.Borrego@Sun.COM return (NT_STATUS_NO_MEMORY); 230*7619SJose.Borrego@Sun.COM 231*7619SJose.Borrego@Sun.COM info->role = DS_ROLE_STANDALONE_SERVER; 232*7619SJose.Borrego@Sun.COM info->flags = 0; 233*7619SJose.Borrego@Sun.COM info->dns_domain = NULL; 234*7619SJose.Borrego@Sun.COM info->forest = NULL; 235*7619SJose.Borrego@Sun.COM bzero(&info->domain_guid, sizeof (ndr_uuid_t)); 236*7619SJose.Borrego@Sun.COM return (NT_STATUS_SUCCESS); 237*7619SJose.Borrego@Sun.COM } 238