Home | History | Annotate | Download | only in common
      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 2010 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     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/libsmbrdr.h>
     44 #include <smbsrv/smbinfo.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, "Failed to update CIFS "
    130 				    "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 int
    146 mlsvc_ping(const char *server)
    147 {
    148 	return (smbrdr_echo(server));
    149 }
    150 
    151 void
    152 mlsvc_disconnect(const char *server)
    153 {
    154 	smbrdr_disconnect(server);
    155 }
    156