1*5331Samw /* 2*5331Samw * CDDL HEADER START 3*5331Samw * 4*5331Samw * The contents of this file are subject to the terms of the 5*5331Samw * Common Development and Distribution License (the "License"). 6*5331Samw * You may not use this file except in compliance with the License. 7*5331Samw * 8*5331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5331Samw * or http://www.opensolaris.org/os/licensing. 10*5331Samw * See the License for the specific language governing permissions 11*5331Samw * and limitations under the License. 12*5331Samw * 13*5331Samw * When distributing Covered Code, include this CDDL HEADER in each 14*5331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5331Samw * If applicable, add the following below this CDDL HEADER, with the 16*5331Samw * fields enclosed by brackets "[]" replaced with your own identifying 17*5331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 18*5331Samw * 19*5331Samw * CDDL HEADER END 20*5331Samw */ 21*5331Samw /* 22*5331Samw * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*5331Samw * Use is subject to license terms. 24*5331Samw */ 25*5331Samw 26*5331Samw #pragma ident "%Z%%M% %I% %E% SMI" 27*5331Samw 28*5331Samw /* 29*5331Samw * Utility functions to support the RPC interface library. 30*5331Samw */ 31*5331Samw 32*5331Samw #include <stdio.h> 33*5331Samw #include <stdarg.h> 34*5331Samw #include <strings.h> 35*5331Samw #include <unistd.h> 36*5331Samw #include <netdb.h> 37*5331Samw #include <stdlib.h> 38*5331Samw #include <pwd.h> 39*5331Samw #include <grp.h> 40*5331Samw 41*5331Samw #include <sys/time.h> 42*5331Samw #include <sys/systm.h> 43*5331Samw 44*5331Samw #include <smbsrv/libsmb.h> 45*5331Samw #include <smbsrv/libsmbrdr.h> 46*5331Samw #include <smbsrv/libsmbns.h> 47*5331Samw #include <smbsrv/libmlsvc.h> 48*5331Samw 49*5331Samw #include <smbsrv/smbinfo.h> 50*5331Samw #include <smbsrv/ntsid.h> 51*5331Samw #include <smbsrv/lsalib.h> 52*5331Samw #include <smbsrv/samlib.h> 53*5331Samw #include <smbsrv/mlsvc_util.h> 54*5331Samw #include <smbsrv/mlsvc.h> 55*5331Samw 56*5331Samw extern int netr_open(char *, char *, mlsvc_handle_t *); 57*5331Samw extern int netr_close(mlsvc_handle_t *); 58*5331Samw extern DWORD netlogon_auth(char *, mlsvc_handle_t *, DWORD); 59*5331Samw extern int mlsvc_user_getauth(char *, char *, smb_auth_info_t *); 60*5331Samw 61*5331Samw static int mlsvc_lookup_local_name(char *name, nt_sid_t **sid); 62*5331Samw static int mlsvc_lookup_nt_name(char *name, nt_sid_t **sid); 63*5331Samw static int mlsvc_lookup_nt_sid(nt_sid_t *sid, char *buf, int bufsize); 64*5331Samw 65*5331Samw /* 66*5331Samw * Compare the supplied domain name with the local hostname. 67*5331Samw * We need to deal with both server names and fully-qualified 68*5331Samw * domain names. 69*5331Samw * 70*5331Samw * Returns: 71*5331Samw * 0 The specified domain is not the local domain, 72*5331Samw * 1 The Specified domain is the local domain. 73*5331Samw * -1 Invalid parameter or unable to get the local 74*5331Samw * system information. 75*5331Samw */ 76*5331Samw int 77*5331Samw mlsvc_is_local_domain(const char *domain) 78*5331Samw { 79*5331Samw char hostname[MAXHOSTNAMELEN]; 80*5331Samw uint32_t mode; 81*5331Samw int rc; 82*5331Samw 83*5331Samw if (strchr(domain, '.') != NULL) 84*5331Samw rc = smb_getfqhostname(hostname, MAXHOSTNAMELEN); 85*5331Samw else 86*5331Samw rc = smb_gethostname(hostname, MAXHOSTNAMELEN, 1); 87*5331Samw 88*5331Samw if (rc != 0) 89*5331Samw return (-1); 90*5331Samw 91*5331Samw rc = strcasecmp(domain, hostname); 92*5331Samw mode = smb_get_security_mode(); 93*5331Samw 94*5331Samw if ((rc == 0) || (mode == SMB_SECMODE_WORKGRP)) 95*5331Samw return (1); 96*5331Samw 97*5331Samw return (0); 98*5331Samw } 99*5331Samw 100*5331Samw /* 101*5331Samw * mlsvc_lookup_name 102*5331Samw * 103*5331Samw * Lookup a name in the specified domain and translate it to a SID. 104*5331Samw * If the name is in the NT domain, it may refer to a user, group or 105*5331Samw * alias. Otherwise it must refer to a UNIX username. The memory for 106*5331Samw * the sid is allocated using malloc so the caller should call free 107*5331Samw * when it is no longer required. 108*5331Samw * 109*5331Samw * On success, 0 will be returned and sid will point to a local domain 110*5331Samw * user SID. Otherwise -1 will be returned. 111*5331Samw */ 112*5331Samw int 113*5331Samw mlsvc_lookup_name(char *domain, char *name, nt_sid_t **sid) 114*5331Samw { 115*5331Samw if (domain == NULL || name == NULL || sid == NULL) 116*5331Samw return (-1); 117*5331Samw 118*5331Samw if (mlsvc_is_local_domain(domain) == 1) 119*5331Samw return (mlsvc_lookup_local_name(name, sid)); 120*5331Samw else 121*5331Samw return (mlsvc_lookup_nt_name(name, sid)); 122*5331Samw } 123*5331Samw 124*5331Samw /* 125*5331Samw * mlsvc_lookup_local_name 126*5331Samw * 127*5331Samw * Lookup a name in the local password file and translate it to a SID. 128*5331Samw * The name must refer to a user. This is a private function intended 129*5331Samw * to support mlsvc_lookup_name so it doesn't perform any parameter 130*5331Samw * validation. The memory for the sid is allocated using malloc so the 131*5331Samw * caller must call free when it is no longer required. 132*5331Samw * 133*5331Samw * On success, 0 will be returned and sid will point to a local domain 134*5331Samw * user SID. Otherwise -1 will be returned. 135*5331Samw */ 136*5331Samw static int 137*5331Samw mlsvc_lookup_local_name(char *name, nt_sid_t **sid) 138*5331Samw { 139*5331Samw struct passwd *pw; 140*5331Samw nt_sid_t *domain_sid; 141*5331Samw 142*5331Samw if ((pw = getpwnam(name)) == NULL) 143*5331Samw return (-1); 144*5331Samw 145*5331Samw if ((domain_sid = nt_domain_local_sid()) == NULL) 146*5331Samw return (-1); 147*5331Samw 148*5331Samw *sid = nt_sid_splice(domain_sid, pw->pw_uid); 149*5331Samw return (0); 150*5331Samw } 151*5331Samw 152*5331Samw /* 153*5331Samw * mlsvc_lookup_nt_name 154*5331Samw * 155*5331Samw * Lookup a name in the specified NT domain and translate it to a SID. 156*5331Samw * The name may refer to a user, group or alias. This is a private 157*5331Samw * function intended to support mlsvc_lookup_name so it doesn't do any 158*5331Samw * parameter validation. The memory for the sid is allocated using 159*5331Samw * malloc so the caller should call free when it is no longer required. 160*5331Samw * 161*5331Samw * On success, 0 will be returned and sid will point to an NT domain 162*5331Samw * user SID. Otherwise -1 will be returned. 163*5331Samw */ 164*5331Samw static int 165*5331Samw mlsvc_lookup_nt_name(char *name, nt_sid_t **sid) 166*5331Samw { 167*5331Samw smb_userinfo_t *user_info; 168*5331Samw 169*5331Samw if ((user_info = mlsvc_alloc_user_info()) == NULL) 170*5331Samw return (-1); 171*5331Samw 172*5331Samw if (lsa_lookup_name(0, 0, name, user_info) != 0) 173*5331Samw return (-1); 174*5331Samw 175*5331Samw *sid = nt_sid_splice(user_info->domain_sid, user_info->rid); 176*5331Samw mlsvc_free_user_info(user_info); 177*5331Samw return (0); 178*5331Samw } 179*5331Samw 180*5331Samw /* 181*5331Samw * mlsvc_lookup_sid 182*5331Samw * 183*5331Samw * Lookup a SID and translate it to a name. The name returned may refer 184*5331Samw * to a domain, user, group or alias dependent on the SID. On success 0 185*5331Samw * will be returned. Otherwise -1 will be returned. 186*5331Samw */ 187*5331Samw int 188*5331Samw mlsvc_lookup_sid(nt_sid_t *sid, char *buf, int bufsize) 189*5331Samw { 190*5331Samw struct passwd *pw; 191*5331Samw struct group *gr; 192*5331Samw nt_group_t *grp; 193*5331Samw DWORD rid; 194*5331Samw 195*5331Samw if (sid == NULL || buf == NULL) 196*5331Samw return (-1); 197*5331Samw 198*5331Samw if (nt_sid_is_local(sid)) { 199*5331Samw (void) nt_sid_get_rid(sid, &rid); 200*5331Samw 201*5331Samw switch (SAM_RID_TYPE(rid)) { 202*5331Samw case SAM_RT_NT_UID: 203*5331Samw break; 204*5331Samw 205*5331Samw case SAM_RT_NT_GID: 206*5331Samw if ((grp = nt_groups_lookup_rid(rid)) == NULL) 207*5331Samw return (-1); 208*5331Samw 209*5331Samw (void) strlcpy(buf, grp->name, bufsize); 210*5331Samw break; 211*5331Samw 212*5331Samw case SAM_RT_UNIX_UID: 213*5331Samw if ((pw = getpwuid(SAM_DECODE_RID(rid))) == NULL) 214*5331Samw return (-1); 215*5331Samw 216*5331Samw (void) strlcpy(buf, pw->pw_name, bufsize); 217*5331Samw break; 218*5331Samw 219*5331Samw case SAM_RT_UNIX_GID: 220*5331Samw if ((gr = getgrgid(SAM_DECODE_RID(rid))) == NULL) 221*5331Samw return (-1); 222*5331Samw 223*5331Samw (void) strlcpy(buf, gr->gr_name, bufsize); 224*5331Samw break; 225*5331Samw } 226*5331Samw 227*5331Samw return (0); 228*5331Samw } 229*5331Samw 230*5331Samw return (mlsvc_lookup_nt_sid(sid, buf, bufsize)); 231*5331Samw } 232*5331Samw 233*5331Samw /* 234*5331Samw * mlsvc_lookup_nt_sid 235*5331Samw * 236*5331Samw * Lookup an NT SID and translate it to a name. This is a private 237*5331Samw * function intended to support mlsvc_lookup_sid so it doesn't do any 238*5331Samw * parameter validation. The input account_name specifies the logon/ 239*5331Samw * session to be used for the lookup. It doesn't need to have any 240*5331Samw * association with the SID being looked up. The name returned may 241*5331Samw * refer to a domain, user, group or alias dependent on the SID. 242*5331Samw * 243*5331Samw * On success the name will be copied into buf and 0 will be returned. 244*5331Samw * Otherwise -1 will be returned. 245*5331Samw */ 246*5331Samw static int 247*5331Samw mlsvc_lookup_nt_sid(nt_sid_t *sid, char *buf, int bufsize) 248*5331Samw { 249*5331Samw smb_userinfo_t *user_info; 250*5331Samw int rc; 251*5331Samw 252*5331Samw if ((user_info = mlsvc_alloc_user_info()) == NULL) 253*5331Samw return (-1); 254*5331Samw 255*5331Samw if ((rc = lsa_lookup_sid(sid, user_info)) == 0) 256*5331Samw (void) strlcpy(buf, user_info->name, bufsize); 257*5331Samw 258*5331Samw mlsvc_free_user_info(user_info); 259*5331Samw return (rc); 260*5331Samw } 261*5331Samw 262*5331Samw /* 263*5331Samw * mlsvc_alloc_user_info 264*5331Samw * 265*5331Samw * Allocate a user_info structure and set the contents to zero. A 266*5331Samw * pointer to the user_info structure is returned. 267*5331Samw */ 268*5331Samw smb_userinfo_t * 269*5331Samw mlsvc_alloc_user_info(void) 270*5331Samw { 271*5331Samw smb_userinfo_t *user_info; 272*5331Samw 273*5331Samw user_info = (smb_userinfo_t *)malloc(sizeof (smb_userinfo_t)); 274*5331Samw if (user_info == NULL) 275*5331Samw return (NULL); 276*5331Samw 277*5331Samw bzero(user_info, sizeof (smb_userinfo_t)); 278*5331Samw return (user_info); 279*5331Samw } 280*5331Samw 281*5331Samw /* 282*5331Samw * mlsvc_free_user_info 283*5331Samw * 284*5331Samw * Free a user_info structure. This function ensures that the contents 285*5331Samw * of the user_info are freed as well as the user_info itself. 286*5331Samw */ 287*5331Samw void 288*5331Samw mlsvc_free_user_info(smb_userinfo_t *user_info) 289*5331Samw { 290*5331Samw if (user_info) { 291*5331Samw mlsvc_release_user_info(user_info); 292*5331Samw free(user_info); 293*5331Samw } 294*5331Samw } 295*5331Samw 296*5331Samw /* 297*5331Samw * mlsvc_release_user_info 298*5331Samw * 299*5331Samw * Release the contents of a user_info structure and zero out the 300*5331Samw * elements but do not free the user_info structure itself. This 301*5331Samw * function cleans out the structure so that it can be reused without 302*5331Samw * worrying about stale contents. 303*5331Samw */ 304*5331Samw void 305*5331Samw mlsvc_release_user_info(smb_userinfo_t *user_info) 306*5331Samw { 307*5331Samw int i; 308*5331Samw 309*5331Samw if (user_info == NULL) 310*5331Samw return; 311*5331Samw 312*5331Samw free(user_info->name); 313*5331Samw free(user_info->domain_sid); 314*5331Samw free(user_info->domain_name); 315*5331Samw free(user_info->groups); 316*5331Samw 317*5331Samw if (user_info->n_other_grps) { 318*5331Samw for (i = 0; i < user_info->n_other_grps; i++) 319*5331Samw free(user_info->other_grps[i].sid); 320*5331Samw 321*5331Samw free(user_info->other_grps); 322*5331Samw } 323*5331Samw 324*5331Samw free(user_info->user_sid); 325*5331Samw free(user_info->pgrp_sid); 326*5331Samw bzero(user_info, sizeof (smb_userinfo_t)); 327*5331Samw } 328*5331Samw 329*5331Samw /* 330*5331Samw * mlsvc_setadmin_user_info 331*5331Samw * 332*5331Samw * Determines if the given user is the domain Administrator or a 333*5331Samw * member of Domain Admins or Administrators group and set the 334*5331Samw * user_info->flags accordingly. 335*5331Samw */ 336*5331Samw void 337*5331Samw mlsvc_setadmin_user_info(smb_userinfo_t *user_info) 338*5331Samw { 339*5331Samw nt_domain_t *domain; 340*5331Samw nt_group_t *grp; 341*5331Samw int i; 342*5331Samw 343*5331Samw if ((domain = nt_domain_lookupbytype(NT_DOMAIN_PRIMARY)) == NULL) 344*5331Samw return; 345*5331Samw 346*5331Samw if (!nt_sid_is_equal((nt_sid_t *)user_info->domain_sid, domain->sid)) 347*5331Samw return; 348*5331Samw 349*5331Samw if (user_info->rid == DOMAIN_USER_RID_ADMIN) 350*5331Samw user_info->flags |= SMB_UINFO_FLAG_DADMIN; 351*5331Samw else if (user_info->primary_group_rid == DOMAIN_GROUP_RID_ADMINS) 352*5331Samw user_info->flags |= SMB_UINFO_FLAG_DADMIN; 353*5331Samw else { 354*5331Samw for (i = 0; i < user_info->n_groups; i++) 355*5331Samw if (user_info->groups[i].rid == DOMAIN_GROUP_RID_ADMINS) 356*5331Samw user_info->flags |= SMB_UINFO_FLAG_DADMIN; 357*5331Samw } 358*5331Samw 359*5331Samw grp = nt_group_getinfo("Administrators", RWLOCK_READER); 360*5331Samw if (grp) { 361*5331Samw i = nt_group_is_member(grp, user_info->user_sid); 362*5331Samw nt_group_putinfo(grp); 363*5331Samw if (i) 364*5331Samw user_info->flags |= SMB_UINFO_FLAG_LADMIN; 365*5331Samw } 366*5331Samw } 367*5331Samw 368*5331Samw /* 369*5331Samw * mlsvc_string_save 370*5331Samw * 371*5331Samw * This is a convenience function to prepare strings for an RPC call. 372*5331Samw * An ms_string_t is set up with the appropriate lengths and str is 373*5331Samw * set up to point to a copy of the original string on the heap. The 374*5331Samw * macro MLRPC_HEAP_STRSAVE is an alias for mlrpc_heap_strsave, which 375*5331Samw * extends the heap and copies the string into the new area. 376*5331Samw */ 377*5331Samw int 378*5331Samw mlsvc_string_save(ms_string_t *ms, char *str, struct mlrpc_xaction *mxa) 379*5331Samw { 380*5331Samw int length; 381*5331Samw char *p; 382*5331Samw 383*5331Samw if (ms == NULL || str == NULL || mxa == NULL) 384*5331Samw return (0); 385*5331Samw 386*5331Samw /* 387*5331Samw * Windows NT expects the name length to exclude the 388*5331Samw * terminating wchar null but doesn't care whether or 389*5331Samw * not the allosize includes it. Windows 2000 insists 390*5331Samw * that both the length and the allosize include the 391*5331Samw * wchar null. 392*5331Samw */ 393*5331Samw length = mts_wcequiv_strlen(str); 394*5331Samw ms->allosize = length + sizeof (mts_wchar_t); 395*5331Samw 396*5331Samw if (mxa->context->user_ctx->du_native_os == NATIVE_OS_WIN2000) 397*5331Samw ms->length = ms->allosize; 398*5331Samw else 399*5331Samw ms->length = length; 400*5331Samw 401*5331Samw if ((p = MLRPC_HEAP_STRSAVE(mxa, str)) == NULL) { 402*5331Samw return (0); 403*5331Samw } 404*5331Samw 405*5331Samw ms->str = (LPTSTR)p; 406*5331Samw return (1); 407*5331Samw } 408*5331Samw 409*5331Samw /* 410*5331Samw * mlsvc_sid_save 411*5331Samw * 412*5331Samw * Expand the heap and copy the sid into the new area. 413*5331Samw * Returns a pointer to the copy of the sid on the heap. 414*5331Samw */ 415*5331Samw nt_sid_t * 416*5331Samw mlsvc_sid_save(nt_sid_t *sid, struct mlrpc_xaction *mxa) 417*5331Samw { 418*5331Samw nt_sid_t *heap_sid; 419*5331Samw unsigned size; 420*5331Samw 421*5331Samw if (sid == NULL) 422*5331Samw return (NULL); 423*5331Samw 424*5331Samw size = nt_sid_length(sid); 425*5331Samw 426*5331Samw if ((heap_sid = (nt_sid_t *)MLRPC_HEAP_MALLOC(mxa, size)) == NULL) 427*5331Samw return (0); 428*5331Samw 429*5331Samw bcopy(sid, heap_sid, size); 430*5331Samw return (heap_sid); 431*5331Samw } 432*5331Samw 433*5331Samw /* 434*5331Samw * mlsvc_is_null_handle 435*5331Samw * 436*5331Samw * Check a handle against a null handle. Returns 1 if the handle is 437*5331Samw * null. Otherwise returns 0. 438*5331Samw */ 439*5331Samw int 440*5331Samw mlsvc_is_null_handle(mlsvc_handle_t *handle) 441*5331Samw { 442*5331Samw static ms_handle_t zero_handle; 443*5331Samw 444*5331Samw if (handle == NULL || handle->context == NULL) 445*5331Samw return (1); 446*5331Samw 447*5331Samw if (!memcmp(&handle->handle, &zero_handle, sizeof (ms_handle_t))) 448*5331Samw return (1); 449*5331Samw 450*5331Samw return (0); 451*5331Samw } 452*5331Samw 453*5331Samw /* 454*5331Samw * mlsvc_validate_user 455*5331Samw * 456*5331Samw * Returns NT status codes. 457*5331Samw */ 458*5331Samw DWORD 459*5331Samw mlsvc_validate_user(char *server, char *domain, char *plain_user, 460*5331Samw char *plain_text) 461*5331Samw { 462*5331Samw smb_auth_info_t auth; 463*5331Samw smb_ntdomain_t *di; 464*5331Samw int erc; 465*5331Samw DWORD status; 466*5331Samw mlsvc_handle_t netr_handle; 467*5331Samw char machine_passwd[MLSVC_MACHINE_ACCT_PASSWD_MAX]; 468*5331Samw 469*5331Samw machine_passwd[0] = '\0'; 470*5331Samw 471*5331Samw /* 472*5331Samw * Ensure that the domain name is uppercase. 473*5331Samw */ 474*5331Samw (void) utf8_strupr(domain); 475*5331Samw 476*5331Samw /* 477*5331Samw * There is no point continuing if the domain information is 478*5331Samw * not available. Wait for up to 10 seconds and then give up. 479*5331Samw */ 480*5331Samw if ((di = smb_getdomaininfo(10)) == 0) { 481*5331Samw status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 482*5331Samw return (status); 483*5331Samw } 484*5331Samw 485*5331Samw if (strcasecmp(domain, di->domain) != 0) { 486*5331Samw status = NT_STATUS_INVALID_PARAMETER; 487*5331Samw return (status); 488*5331Samw } 489*5331Samw 490*5331Samw erc = mlsvc_user_logon(server, domain, plain_user, plain_text); 491*5331Samw 492*5331Samw if (erc == AUTH_USER_GRANT) { 493*5331Samw int isenabled; 494*5331Samw 495*5331Samw smb_config_rdlock(); 496*5331Samw isenabled = smb_config_getyorn(SMB_CI_ADS_ENABLE); 497*5331Samw smb_config_unlock(); 498*5331Samw if (isenabled) { 499*5331Samw if (adjoin(machine_passwd, 500*5331Samw sizeof (machine_passwd)) == ADJOIN_SUCCESS) { 501*5331Samw status = NT_STATUS_SUCCESS; 502*5331Samw } else { 503*5331Samw status = NT_STATUS_UNSUCCESSFUL; 504*5331Samw } 505*5331Samw } else { 506*5331Samw /* 507*5331Samw * Ensure that we don't have an old account in 508*5331Samw * this domain. There's no need to check the 509*5331Samw * return status. 510*5331Samw */ 511*5331Samw (void) sam_remove_trust_account(server, domain); 512*5331Samw 513*5331Samw if (mlsvc_user_getauth(server, plain_user, &auth) 514*5331Samw != 0) { 515*5331Samw status = NT_STATUS_INVALID_PARAMETER; 516*5331Samw return (status); 517*5331Samw } 518*5331Samw 519*5331Samw status = sam_create_trust_account(server, domain, 520*5331Samw &auth); 521*5331Samw if (status == NT_STATUS_SUCCESS) { 522*5331Samw (void) smb_gethostname(machine_passwd, 523*5331Samw sizeof (machine_passwd), 0); 524*5331Samw (void) utf8_strlwr(machine_passwd); 525*5331Samw } 526*5331Samw } 527*5331Samw 528*5331Samw if (status == NT_STATUS_SUCCESS) { 529*5331Samw smb_config_wrlock(); 530*5331Samw if (smb_config_set(SMB_CI_MACHINE_PASSWD, 531*5331Samw machine_passwd) != 0) { 532*5331Samw smb_config_unlock(); 533*5331Samw return (NT_STATUS_UNSUCCESSFUL); 534*5331Samw } 535*5331Samw smb_config_unlock(); 536*5331Samw 537*5331Samw /* 538*5331Samw * If we successfully create a trust account, we mark 539*5331Samw * ourselves as a domain member in the environment so 540*5331Samw * that we use the SAMLOGON version of the NETLOGON 541*5331Samw * PDC location protocol. 542*5331Samw */ 543*5331Samw smb_set_domain_member(1); 544*5331Samw 545*5331Samw if (netr_open(server, domain, &netr_handle) == 0) { 546*5331Samw status = netlogon_auth(server, &netr_handle, 547*5331Samw NETR_FLG_INIT); 548*5331Samw (void) netr_close(&netr_handle); 549*5331Samw } else { 550*5331Samw status = NT_STATUS_OPEN_FAILED; 551*5331Samw } 552*5331Samw } 553*5331Samw } else { 554*5331Samw status = NT_STATUS_LOGON_FAILURE; 555*5331Samw } 556*5331Samw 557*5331Samw return (status); 558*5331Samw } 559*5331Samw 560*5331Samw /*ARGSUSED*/ 561*5331Samw void 562*5331Samw nt_group_ht_lock(krwmode_t locktype) 563*5331Samw { 564*5331Samw } 565*5331Samw 566*5331Samw void 567*5331Samw nt_group_ht_unlock(void) 568*5331Samw { 569*5331Samw } 570*5331Samw 571*5331Samw int 572*5331Samw nt_group_num_groups(void) 573*5331Samw { 574*5331Samw return (0); 575*5331Samw } 576*5331Samw 577*5331Samw /*ARGSUSED*/ 578*5331Samw uint32_t 579*5331Samw nt_group_add(char *gname, char *comment) 580*5331Samw { 581*5331Samw return (NT_STATUS_NOT_SUPPORTED); 582*5331Samw } 583*5331Samw 584*5331Samw /*ARGSUSED*/ 585*5331Samw uint32_t 586*5331Samw nt_group_modify(char *gname, char *new_gname, char *comment) 587*5331Samw { 588*5331Samw return (NT_STATUS_NOT_SUPPORTED); 589*5331Samw } 590*5331Samw 591*5331Samw /*ARGSUSED*/ 592*5331Samw uint32_t 593*5331Samw nt_group_delete(char *gname) 594*5331Samw { 595*5331Samw return (NT_STATUS_NOT_SUPPORTED); 596*5331Samw } 597*5331Samw 598*5331Samw /*ARGSUSED*/ 599*5331Samw nt_group_t * 600*5331Samw nt_group_getinfo(char *gname, krwmode_t locktype) 601*5331Samw { 602*5331Samw return (NULL); 603*5331Samw } 604*5331Samw 605*5331Samw /*ARGSUSED*/ 606*5331Samw void 607*5331Samw nt_group_putinfo(nt_group_t *grp) 608*5331Samw { 609*5331Samw } 610*5331Samw 611*5331Samw /*ARGSUSED*/ 612*5331Samw int 613*5331Samw nt_group_getpriv(nt_group_t *grp, uint32_t priv_id) 614*5331Samw { 615*5331Samw return (SE_PRIVILEGE_DISABLED); 616*5331Samw } 617*5331Samw 618*5331Samw /*ARGSUSED*/ 619*5331Samw uint32_t 620*5331Samw nt_group_setpriv(nt_group_t *grp, uint32_t priv_id, uint32_t new_attr) 621*5331Samw { 622*5331Samw return (NT_STATUS_NOT_SUPPORTED); 623*5331Samw } 624*5331Samw 625*5331Samw /*ARGSUSED*/ 626*5331Samw int 627*5331Samw nt_group_is_member(nt_group_t *grp, nt_sid_t *sid) 628*5331Samw { 629*5331Samw return (0); 630*5331Samw } 631*5331Samw 632*5331Samw /*ARGSUSED*/ 633*5331Samw uint32_t 634*5331Samw nt_group_add_member(nt_group_t *grp, nt_sid_t *msid, uint16_t sid_name_use, 635*5331Samw char *account) 636*5331Samw { 637*5331Samw return (NT_STATUS_NOT_SUPPORTED); 638*5331Samw } 639*5331Samw 640*5331Samw /*ARGSUSED*/ 641*5331Samw uint32_t 642*5331Samw nt_group_del_member(nt_group_t *grp, void *key, int keytype) 643*5331Samw { 644*5331Samw return (NT_STATUS_NOT_SUPPORTED); 645*5331Samw } 646*5331Samw 647*5331Samw /*ARGSUSED*/ 648*5331Samw int 649*5331Samw nt_group_num_members(nt_group_t *grp) 650*5331Samw { 651*5331Samw return (0); 652*5331Samw } 653*5331Samw 654*5331Samw nt_group_iterator_t * 655*5331Samw nt_group_open_iterator(void) 656*5331Samw { 657*5331Samw return (NULL); 658*5331Samw } 659*5331Samw 660*5331Samw /*ARGSUSED*/ 661*5331Samw void 662*5331Samw nt_group_close_iterator(nt_group_iterator_t *gi) 663*5331Samw { 664*5331Samw } 665*5331Samw 666*5331Samw /*ARGSUSED*/ 667*5331Samw nt_group_t * 668*5331Samw nt_group_iterate(nt_group_iterator_t *gi) 669*5331Samw { 670*5331Samw return (NULL); 671*5331Samw } 672*5331Samw 673*5331Samw int 674*5331Samw nt_group_cache_size(void) 675*5331Samw { 676*5331Samw return (0); 677*5331Samw } 678*5331Samw 679*5331Samw uint32_t 680*5331Samw sam_init(void) 681*5331Samw { 682*5331Samw return (NT_STATUS_SUCCESS); 683*5331Samw } 684*5331Samw 685*5331Samw /*ARGSUSED*/ 686*5331Samw uint32_t 687*5331Samw nt_group_add_member_byname(char *gname, char *account) 688*5331Samw { 689*5331Samw return (NT_STATUS_NOT_SUPPORTED); 690*5331Samw } 691*5331Samw 692*5331Samw /*ARGSUSED*/ 693*5331Samw uint32_t 694*5331Samw nt_group_del_member_byname(nt_group_t *grp, char *member_name) 695*5331Samw { 696*5331Samw return (NT_STATUS_NOT_SUPPORTED); 697*5331Samw } 698*5331Samw 699*5331Samw /*ARGSUSED*/ 700*5331Samw void 701*5331Samw nt_group_add_groupprivs(nt_group_t *grp, smb_privset_t *priv) 702*5331Samw { 703*5331Samw } 704*5331Samw 705*5331Samw /*ARGSUSED*/ 706*5331Samw uint32_t 707*5331Samw nt_groups_member_privs(nt_sid_t *sid, smb_privset_t *priv) 708*5331Samw { 709*5331Samw return (NT_STATUS_SUCCESS); 710*5331Samw } 711*5331Samw 712*5331Samw /*ARGSUSED*/ 713*5331Samw int 714*5331Samw nt_groups_member_ngroups(nt_sid_t *sid) 715*5331Samw { 716*5331Samw return (0); 717*5331Samw } 718*5331Samw 719*5331Samw /*ARGSUSED*/ 720*5331Samw uint32_t 721*5331Samw nt_groups_member_groups(nt_sid_t *sid, smb_id_t *grps, int ngrps) 722*5331Samw { 723*5331Samw return (NT_STATUS_SUCCESS); 724*5331Samw } 725*5331Samw 726*5331Samw /*ARGSUSED*/ 727*5331Samw nt_group_t * 728*5331Samw nt_groups_lookup_rid(uint32_t rid) 729*5331Samw { 730*5331Samw return (NULL); 731*5331Samw } 732*5331Samw 733*5331Samw /*ARGSUSED*/ 734*5331Samw int 735*5331Samw nt_groups_count(int cnt_opt) 736*5331Samw { 737*5331Samw return (0); 738*5331Samw } 739*5331Samw 740*5331Samw /*ARGSUSED*/ 741*5331Samw int 742*5331Samw nt_group_member_list(int offset, nt_group_t *grp, 743*5331Samw ntgrp_member_list_t *rmembers) 744*5331Samw { 745*5331Samw return (0); 746*5331Samw } 747*5331Samw 748*5331Samw /*ARGSUSED*/ 749*5331Samw void 750*5331Samw nt_group_list(int offset, char *pattern, ntgrp_list_t *list) 751*5331Samw { 752*5331Samw } 753