15331Samw /* 25331Samw * CDDL HEADER START 35331Samw * 45331Samw * The contents of this file are subject to the terms of the 55331Samw * Common Development and Distribution License (the "License"). 65331Samw * You may not use this file except in compliance with the License. 75331Samw * 85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95331Samw * or http://www.opensolaris.org/os/licensing. 105331Samw * See the License for the specific language governing permissions 115331Samw * and limitations under the License. 125331Samw * 135331Samw * When distributing Covered Code, include this CDDL HEADER in each 145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155331Samw * If applicable, add the following below this CDDL HEADER, with the 165331Samw * fields enclosed by brackets "[]" replaced with your own identifying 175331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 185331Samw * 195331Samw * CDDL HEADER END 205331Samw */ 215331Samw /* 22*8474SJose.Borrego@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 235331Samw * Use is subject to license terms. 245331Samw */ 255331Samw 265331Samw /* 275331Samw * Utility functions to support the RPC interface library. 285331Samw */ 295331Samw 305331Samw #include <stdio.h> 315331Samw #include <stdarg.h> 325331Samw #include <strings.h> 335331Samw #include <unistd.h> 345331Samw #include <netdb.h> 355331Samw #include <stdlib.h> 365331Samw #include <sys/time.h> 375331Samw #include <sys/systm.h> 385331Samw 395331Samw #include <smbsrv/libsmb.h> 405331Samw #include <smbsrv/libsmbrdr.h> 415331Samw #include <smbsrv/libsmbns.h> 425331Samw #include <smbsrv/libmlsvc.h> 435331Samw #include <smbsrv/smbinfo.h> 448334SJose.Borrego@Sun.COM #include <lsalib.h> 458334SJose.Borrego@Sun.COM #include <samlib.h> 468334SJose.Borrego@Sun.COM #include <smbsrv/netrauth.h> 475331Samw 485772Sas200622 /* Domain join support (using MS-RPC) */ 495772Sas200622 static boolean_t mlsvc_ntjoin_support = B_FALSE; 505772Sas200622 515331Samw extern int netr_open(char *, char *, mlsvc_handle_t *); 525331Samw extern int netr_close(mlsvc_handle_t *); 535331Samw extern DWORD netlogon_auth(char *, mlsvc_handle_t *, DWORD); 545331Samw extern int mlsvc_user_getauth(char *, char *, smb_auth_info_t *); 555331Samw 565331Samw /* 575331Samw * mlsvc_lookup_name 585331Samw * 595772Sas200622 * This is just a wrapper for lsa_lookup_name. 605331Samw * 615772Sas200622 * The memory for the sid is allocated using malloc so the caller should 625772Sas200622 * call free when it is no longer required. 635331Samw */ 645772Sas200622 uint32_t 656432Sas200622 mlsvc_lookup_name(char *account, smb_sid_t **sid, uint16_t *sid_type) 665331Samw { 675772Sas200622 smb_userinfo_t *ainfo; 685772Sas200622 uint32_t status; 695331Samw 705772Sas200622 if ((ainfo = mlsvc_alloc_user_info()) == NULL) 715772Sas200622 return (NT_STATUS_NO_MEMORY); 725331Samw 738334SJose.Borrego@Sun.COM status = lsa_lookup_name(account, *sid_type, ainfo); 745772Sas200622 if (status == NT_STATUS_SUCCESS) { 755772Sas200622 *sid = ainfo->user_sid; 765772Sas200622 ainfo->user_sid = NULL; 775772Sas200622 *sid_type = ainfo->sid_name_use; 785772Sas200622 } 795331Samw 805772Sas200622 mlsvc_free_user_info(ainfo); 815772Sas200622 return (status); 825331Samw } 835331Samw 845331Samw /* 855331Samw * mlsvc_lookup_sid 865331Samw * 875772Sas200622 * This is just a wrapper for lsa_lookup_sid. 885772Sas200622 * 895772Sas200622 * The allocated memory for the returned name must be freed by caller upon 905772Sas200622 * successful return. 915331Samw */ 925772Sas200622 uint32_t 936432Sas200622 mlsvc_lookup_sid(smb_sid_t *sid, char **name) 945331Samw { 955772Sas200622 smb_userinfo_t *ainfo; 965772Sas200622 uint32_t status; 975772Sas200622 int namelen; 985331Samw 995772Sas200622 if ((ainfo = mlsvc_alloc_user_info()) == NULL) 1005772Sas200622 return (NT_STATUS_NO_MEMORY); 1015331Samw 1025772Sas200622 status = lsa_lookup_sid(sid, ainfo); 1035772Sas200622 if (status == NT_STATUS_SUCCESS) { 1045772Sas200622 namelen = strlen(ainfo->domain_name) + strlen(ainfo->name) + 2; 1055772Sas200622 if ((*name = malloc(namelen)) == NULL) { 1065772Sas200622 mlsvc_free_user_info(ainfo); 1075772Sas200622 return (NT_STATUS_NO_MEMORY); 1085331Samw } 1095772Sas200622 (void) snprintf(*name, namelen, "%s\\%s", 1105772Sas200622 ainfo->domain_name, ainfo->name); 1115331Samw } 1125331Samw 1135772Sas200622 mlsvc_free_user_info(ainfo); 1145772Sas200622 return (status); 1155331Samw } 1165331Samw 1175331Samw /* 1185331Samw * mlsvc_alloc_user_info 1195331Samw * 1205331Samw * Allocate a user_info structure and set the contents to zero. A 1215331Samw * pointer to the user_info structure is returned. 1225331Samw */ 1235331Samw smb_userinfo_t * 1245331Samw mlsvc_alloc_user_info(void) 1255331Samw { 1265331Samw smb_userinfo_t *user_info; 1275331Samw 1285331Samw user_info = (smb_userinfo_t *)malloc(sizeof (smb_userinfo_t)); 1295331Samw if (user_info == NULL) 1305331Samw return (NULL); 1315331Samw 1325331Samw bzero(user_info, sizeof (smb_userinfo_t)); 1335331Samw return (user_info); 1345331Samw } 1355331Samw 1365331Samw /* 1375331Samw * mlsvc_free_user_info 1385331Samw * 1395331Samw * Free a user_info structure. This function ensures that the contents 1405331Samw * of the user_info are freed as well as the user_info itself. 1415331Samw */ 1425331Samw void 1435331Samw mlsvc_free_user_info(smb_userinfo_t *user_info) 1445331Samw { 1455331Samw if (user_info) { 1465331Samw mlsvc_release_user_info(user_info); 1475331Samw free(user_info); 1485331Samw } 1495331Samw } 1505331Samw 1515331Samw /* 1525331Samw * mlsvc_release_user_info 1535331Samw * 1545331Samw * Release the contents of a user_info structure and zero out the 1555331Samw * elements but do not free the user_info structure itself. This 1565331Samw * function cleans out the structure so that it can be reused without 1575331Samw * worrying about stale contents. 1585331Samw */ 1595331Samw void 1605331Samw mlsvc_release_user_info(smb_userinfo_t *user_info) 1615331Samw { 1625331Samw int i; 1635331Samw 1645331Samw if (user_info == NULL) 1655331Samw return; 1665331Samw 1675331Samw free(user_info->name); 1685331Samw free(user_info->domain_sid); 1695331Samw free(user_info->domain_name); 1705331Samw free(user_info->groups); 1715331Samw 1725331Samw if (user_info->n_other_grps) { 1735331Samw for (i = 0; i < user_info->n_other_grps; i++) 1745331Samw free(user_info->other_grps[i].sid); 1755331Samw 1765331Samw free(user_info->other_grps); 1775331Samw } 1785331Samw 1796849Sjb150015 free(user_info->session_key); 1805331Samw free(user_info->user_sid); 1815331Samw free(user_info->pgrp_sid); 1825331Samw bzero(user_info, sizeof (smb_userinfo_t)); 1835331Samw } 1845331Samw 1855331Samw /* 1865331Samw * mlsvc_setadmin_user_info 1875331Samw * 1885331Samw * Determines if the given user is the domain Administrator or a 1895331Samw * member of Domain Admins or Administrators group and set the 1905331Samw * user_info->flags accordingly. 1915331Samw */ 1925331Samw void 1935331Samw mlsvc_setadmin_user_info(smb_userinfo_t *user_info) 1945331Samw { 1955331Samw nt_domain_t *domain; 1965772Sas200622 smb_group_t grp; 1975772Sas200622 int rc, i; 1985331Samw 1995331Samw if ((domain = nt_domain_lookupbytype(NT_DOMAIN_PRIMARY)) == NULL) 2005331Samw return; 2015331Samw 2026432Sas200622 if (!smb_sid_cmp((smb_sid_t *)user_info->domain_sid, domain->sid)) 2035331Samw return; 2045331Samw 2055331Samw if (user_info->rid == DOMAIN_USER_RID_ADMIN) 2065331Samw user_info->flags |= SMB_UINFO_FLAG_DADMIN; 2075331Samw else if (user_info->primary_group_rid == DOMAIN_GROUP_RID_ADMINS) 2085331Samw user_info->flags |= SMB_UINFO_FLAG_DADMIN; 2095331Samw else { 2105331Samw for (i = 0; i < user_info->n_groups; i++) 2115331Samw if (user_info->groups[i].rid == DOMAIN_GROUP_RID_ADMINS) 2125331Samw user_info->flags |= SMB_UINFO_FLAG_DADMIN; 2135331Samw } 2145331Samw 2155772Sas200622 rc = smb_lgrp_getbyname("Administrators", &grp); 2165772Sas200622 if (rc == SMB_LGRP_SUCCESS) { 2175772Sas200622 if (smb_lgrp_is_member(&grp, user_info->user_sid)) 2185331Samw user_info->flags |= SMB_UINFO_FLAG_LADMIN; 2195772Sas200622 smb_lgrp_free(&grp); 2205331Samw } 2215331Samw } 2225331Samw 2236139Sjb150015 DWORD 2246139Sjb150015 mlsvc_netlogon(char *server, char *domain) 2256139Sjb150015 { 2266139Sjb150015 mlsvc_handle_t netr_handle; 2276139Sjb150015 DWORD status; 2286139Sjb150015 2296139Sjb150015 if (netr_open(server, domain, &netr_handle) == 0) { 2306139Sjb150015 status = netlogon_auth(server, &netr_handle, 2316139Sjb150015 NETR_FLG_INIT); 2326139Sjb150015 (void) netr_close(&netr_handle); 2336139Sjb150015 } else { 2346139Sjb150015 status = NT_STATUS_OPEN_FAILED; 2356139Sjb150015 } 2366139Sjb150015 2376139Sjb150015 return (status); 2386139Sjb150015 } 2396139Sjb150015 2405331Samw /* 2415521Sas200622 * mlsvc_join 2425331Samw * 2435331Samw * Returns NT status codes. 2445331Samw */ 2455331Samw DWORD 2468334SJose.Borrego@Sun.COM mlsvc_join(smb_domain_t *dinfo, char *user, char *plain_text) 2475331Samw { 2485331Samw smb_auth_info_t auth; 2495331Samw int erc; 2505331Samw DWORD status; 2518334SJose.Borrego@Sun.COM char machine_passwd[NETR_MACHINE_ACCT_PASSWD_MAX]; 2525331Samw 2535331Samw machine_passwd[0] = '\0'; 2545331Samw 2555331Samw /* 2565331Samw * Ensure that the domain name is uppercase. 2575331Samw */ 2588334SJose.Borrego@Sun.COM (void) utf8_strupr(dinfo->d_nbdomain); 2595331Samw 2608334SJose.Borrego@Sun.COM erc = mlsvc_logon(dinfo->d_dc, dinfo->d_nbdomain, user); 2615331Samw 2625331Samw if (erc == AUTH_USER_GRANT) { 2635772Sas200622 if (mlsvc_ntjoin_support == B_FALSE) { 2645331Samw 2658334SJose.Borrego@Sun.COM if (smb_ads_join(dinfo->d_fqdomain, user, plain_text, 2665772Sas200622 machine_passwd, sizeof (machine_passwd)) 2677052Samw == SMB_ADJOIN_SUCCESS) 2685331Samw status = NT_STATUS_SUCCESS; 2695521Sas200622 else 2705331Samw status = NT_STATUS_UNSUCCESSFUL; 2715331Samw } else { 2728334SJose.Borrego@Sun.COM if (mlsvc_user_getauth(dinfo->d_dc, user, &auth) 2735331Samw != 0) { 2745331Samw status = NT_STATUS_INVALID_PARAMETER; 2755331Samw return (status); 2765331Samw } 2775331Samw 2788334SJose.Borrego@Sun.COM status = sam_create_trust_account(dinfo->d_dc, 2798334SJose.Borrego@Sun.COM dinfo->d_nbdomain, &auth); 2805331Samw if (status == NT_STATUS_SUCCESS) { 2817961SNatalie.Li@Sun.COM (void) smb_getnetbiosname(machine_passwd, 2827961SNatalie.Li@Sun.COM sizeof (machine_passwd)); 2835331Samw (void) utf8_strlwr(machine_passwd); 2845331Samw } 2855331Samw } 2865331Samw 2875331Samw if (status == NT_STATUS_SUCCESS) { 2888334SJose.Borrego@Sun.COM erc = smb_setdomainprops(NULL, dinfo->d_dc, 2895772Sas200622 machine_passwd); 2906139Sjb150015 if (erc != 0) 2915331Samw return (NT_STATUS_UNSUCCESSFUL); 2925331Samw 2938334SJose.Borrego@Sun.COM status = mlsvc_netlogon(dinfo->d_dc, dinfo->d_nbdomain); 2945331Samw } 2955331Samw } else { 2965331Samw status = NT_STATUS_LOGON_FAILURE; 2975331Samw } 2985331Samw 2995331Samw return (status); 3005331Samw } 301