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 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 /* 26 * Utility functions to support the RPC interface library. 27 */ 28 29 #include <stdio.h> 30 #include <stdarg.h> 31 #include <strings.h> 32 #include <unistd.h> 33 #include <netdb.h> 34 #include <stdlib.h> 35 #include <sys/time.h> 36 #include <sys/systm.h> 37 #include <syslog.h> 38 39 #include <smbsrv/libsmb.h> 40 #include <smbsrv/libsmbns.h> 41 #include <smbsrv/libmlsvc.h> 42 #include <smbsrv/libsmbrdr.h> 43 #include <smbsrv/smbinfo.h> 44 #include <lsalib.h> 45 #include <samlib.h> 46 #include <smbsrv/netrauth.h> 47 48 /* Domain join support (using MS-RPC) */ 49 static boolean_t mlsvc_ntjoin_support = B_FALSE; 50 51 extern int netr_open(char *, char *, mlsvc_handle_t *); 52 extern int netr_close(mlsvc_handle_t *); 53 extern DWORD netlogon_auth(char *, mlsvc_handle_t *, DWORD); 54 55 DWORD 56 mlsvc_netlogon(char *server, char *domain) 57 { 58 mlsvc_handle_t netr_handle; 59 DWORD status; 60 61 if (netr_open(server, domain, &netr_handle) == 0) { 62 if ((status = netlogon_auth(server, &netr_handle, 63 NETR_FLG_INIT)) != NT_STATUS_SUCCESS) 64 syslog(LOG_NOTICE, "Failed to establish NETLOGON " 65 "credential chain"); 66 (void) netr_close(&netr_handle); 67 } else { 68 status = NT_STATUS_OPEN_FAILED; 69 } 70 71 return (status); 72 } 73 74 /* 75 * Joins the specified domain by creating a machine account on 76 * the selected domain controller. 77 * 78 * Disconnect any existing connection with the domain controller. 79 * This will ensure that no stale connection will be used, it will 80 * also pickup any configuration changes in either side by trying 81 * to establish a new connection. 82 * 83 * Returns NT status codes. 84 */ 85 DWORD 86 mlsvc_join(smb_domainex_t *dxi, char *user, char *plain_text) 87 { 88 int erc; 89 DWORD status; 90 char machine_passwd[NETR_MACHINE_ACCT_PASSWD_MAX]; 91 smb_adjoin_status_t err; 92 smb_domain_t *domain; 93 94 machine_passwd[0] = '\0'; 95 96 domain = &dxi->d_primary; 97 98 mlsvc_disconnect(dxi->d_dc); 99 100 erc = smbrdr_logon(dxi->d_dc, domain->di_nbname, user); 101 102 if (erc == AUTH_USER_GRANT) { 103 if (mlsvc_ntjoin_support == B_FALSE) { 104 105 if ((err = smb_ads_join(domain->di_fqname, user, 106 plain_text, machine_passwd, 107 sizeof (machine_passwd))) == SMB_ADJOIN_SUCCESS) { 108 status = NT_STATUS_SUCCESS; 109 } else { 110 smb_ads_join_errmsg(err); 111 status = NT_STATUS_UNSUCCESSFUL; 112 } 113 } else { 114 115 status = sam_create_trust_account(dxi->d_dc, 116 domain->di_nbname); 117 if (status == NT_STATUS_SUCCESS) { 118 (void) smb_getnetbiosname(machine_passwd, 119 sizeof (machine_passwd)); 120 (void) smb_strlwr(machine_passwd); 121 } 122 } 123 124 if (status == NT_STATUS_SUCCESS) { 125 erc = smb_setdomainprops(NULL, dxi->d_dc, 126 machine_passwd); 127 if (erc != 0) { 128 syslog(LOG_NOTICE, 129 "Failed to update configuration"); 130 bzero(machine_passwd, sizeof (machine_passwd)); 131 return (NT_STATUS_UNSUCCESSFUL); 132 } 133 134 status = mlsvc_netlogon(dxi->d_dc, domain->di_nbname); 135 } 136 } else { 137 status = NT_STATUS_LOGON_FAILURE; 138 } 139 140 bzero(machine_passwd, sizeof (machine_passwd)); 141 return (status); 142 } 143 144 void 145 mlsvc_disconnect(const char *server) 146 { 147 smbrdr_disconnect(server); 148 } 149