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