1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21da6c28aaSamw /* 227f667e74Sjose borrego * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23da6c28aaSamw * Use is subject to license terms. 24da6c28aaSamw */ 25da6c28aaSamw 26da6c28aaSamw #ifndef _KERNEL 27da6c28aaSamw #include <stdio.h> 28da6c28aaSamw #include <strings.h> 29da6c28aaSamw #include <stdlib.h> 30da6c28aaSamw #include <syslog.h> 31da6c28aaSamw #include <smbsrv/libsmb.h> 32da6c28aaSamw #else /* _KERNEL */ 33da6c28aaSamw #include <sys/types.h> 34da6c28aaSamw #include <sys/sunddi.h> 35da6c28aaSamw #endif /* _KERNEL */ 36da6c28aaSamw 376537f381Sas200622 #include <smbsrv/smb_sid.h> 38da6c28aaSamw 396537f381Sas200622 static smb_sid_t *smb_sid_alloc(size_t); 40da6c28aaSamw 41da6c28aaSamw /* 426537f381Sas200622 * smb_sid_isvalid 43da6c28aaSamw * 446537f381Sas200622 * Performs a minimal SID validation. 45da6c28aaSamw */ 466537f381Sas200622 boolean_t 476537f381Sas200622 smb_sid_isvalid(smb_sid_t *sid) 48da6c28aaSamw { 496537f381Sas200622 if (sid == NULL) 506537f381Sas200622 return (B_FALSE); 51da6c28aaSamw 526537f381Sas200622 return ((sid->sid_revision == NT_SID_REVISION) && 536537f381Sas200622 (sid->sid_subauthcnt < NT_SID_SUBAUTH_MAX)); 54da6c28aaSamw } 55da6c28aaSamw 56da6c28aaSamw /* 576537f381Sas200622 * smb_sid_len 58da6c28aaSamw * 59da6c28aaSamw * Returns the number of bytes required to hold the sid. 60da6c28aaSamw */ 61da6c28aaSamw int 626537f381Sas200622 smb_sid_len(smb_sid_t *sid) 63da6c28aaSamw { 646537f381Sas200622 if (sid == NULL) 65da6c28aaSamw return (0); 66da6c28aaSamw 676537f381Sas200622 return (sizeof (smb_sid_t) - sizeof (uint32_t) 686537f381Sas200622 + (sid->sid_subauthcnt * sizeof (uint32_t))); 69da6c28aaSamw } 70da6c28aaSamw 71da6c28aaSamw /* 726537f381Sas200622 * smb_sid_dup 73da6c28aaSamw * 746537f381Sas200622 * Make a duplicate of the specified sid. The memory for the new sid 756537f381Sas200622 * should be freed by calling smb_sid_free(). 766537f381Sas200622 * A pointer to the new sid is returned. 77da6c28aaSamw */ 786537f381Sas200622 smb_sid_t * 796537f381Sas200622 smb_sid_dup(smb_sid_t *sid) 80da6c28aaSamw { 816537f381Sas200622 smb_sid_t *new_sid; 82da6c28aaSamw int size; 83da6c28aaSamw 846537f381Sas200622 if (sid == NULL) 856537f381Sas200622 return (NULL); 86da6c28aaSamw 876537f381Sas200622 size = smb_sid_len(sid); 886537f381Sas200622 if ((new_sid = smb_sid_alloc(size)) == NULL) 896537f381Sas200622 return (NULL); 90da6c28aaSamw 916537f381Sas200622 bcopy(sid, new_sid, size); 92da6c28aaSamw return (new_sid); 93da6c28aaSamw } 94da6c28aaSamw 95da6c28aaSamw 96da6c28aaSamw /* 976537f381Sas200622 * smb_sid_splice 98da6c28aaSamw * 996537f381Sas200622 * Make a full sid from a domain sid and a relative id (rid). 1006537f381Sas200622 * The memory for the result sid should be freed by calling 1016537f381Sas200622 * smb_sid_free(). A pointer to the new sid is returned. 102da6c28aaSamw */ 1036537f381Sas200622 smb_sid_t * 1046537f381Sas200622 smb_sid_splice(smb_sid_t *domain_sid, uint32_t rid) 105da6c28aaSamw { 1066537f381Sas200622 smb_sid_t *sid; 107da6c28aaSamw int size; 108da6c28aaSamw 1096537f381Sas200622 if (domain_sid == NULL) 1106537f381Sas200622 return (NULL); 111da6c28aaSamw 1126537f381Sas200622 size = smb_sid_len(domain_sid); 1136537f381Sas200622 if ((sid = smb_sid_alloc(size + sizeof (rid))) == NULL) 1146537f381Sas200622 return (NULL); 115da6c28aaSamw 1166537f381Sas200622 bcopy(domain_sid, sid, size); 117da6c28aaSamw 1186537f381Sas200622 sid->sid_subauth[domain_sid->sid_subauthcnt] = rid; 1196537f381Sas200622 ++sid->sid_subauthcnt; 120da6c28aaSamw 121da6c28aaSamw return (sid); 122da6c28aaSamw } 123da6c28aaSamw 124da6c28aaSamw /* 1256537f381Sas200622 * smb_sid_getrid 126da6c28aaSamw * 1276537f381Sas200622 * Return the Relative Id (RID) of the specified SID. It is the 128da6c28aaSamw * caller's responsibility to ensure that this is an appropriate SID. 129da6c28aaSamw * All we do here is return the last sub-authority from the SID. 130da6c28aaSamw */ 131da6c28aaSamw int 1326537f381Sas200622 smb_sid_getrid(smb_sid_t *sid, uint32_t *rid) 133da6c28aaSamw { 1346537f381Sas200622 if (!smb_sid_isvalid(sid) || (rid == NULL) || 1356537f381Sas200622 (sid->sid_subauthcnt == 0)) 136da6c28aaSamw return (-1); 137da6c28aaSamw 1386537f381Sas200622 *rid = sid->sid_subauth[sid->sid_subauthcnt - 1]; 139da6c28aaSamw return (0); 140da6c28aaSamw } 141da6c28aaSamw 142da6c28aaSamw /* 1436537f381Sas200622 * smb_sid_split 144da6c28aaSamw * 1456537f381Sas200622 * Take a full sid and split it into a domain sid and a relative id (rid). 1467f667e74Sjose borrego * The domain SID is allocated and a pointer to it will be returned. The 1477f667e74Sjose borrego * RID value is passed back in 'rid' arg if it's not NULL. The allocated 1487f667e74Sjose borrego * memory for the domain SID must be freed by caller. 149da6c28aaSamw */ 1507f667e74Sjose borrego smb_sid_t * 1516537f381Sas200622 smb_sid_split(smb_sid_t *sid, uint32_t *rid) 152da6c28aaSamw { 1537f667e74Sjose borrego smb_sid_t *domsid; 154da6c28aaSamw 1557f667e74Sjose borrego if (!smb_sid_isvalid(sid) || (sid->sid_subauthcnt == 0)) 1567f667e74Sjose borrego return (NULL); 1577f667e74Sjose borrego 1587f667e74Sjose borrego if ((domsid = smb_sid_dup(sid)) == NULL) 1597f667e74Sjose borrego return (NULL); 1607f667e74Sjose borrego 1617f667e74Sjose borrego --domsid->sid_subauthcnt; 162da6c28aaSamw if (rid) 1637f667e74Sjose borrego *rid = domsid->sid_subauth[domsid->sid_subauthcnt]; 1647f667e74Sjose borrego 1657f667e74Sjose borrego return (domsid); 166da6c28aaSamw } 167da6c28aaSamw 168da6c28aaSamw /* 1696537f381Sas200622 * smb_sid_splitstr 170da6c28aaSamw * 1716537f381Sas200622 * Takes a full sid in string form and split it into a domain sid and a 1726537f381Sas200622 * relative id (rid). 1736537f381Sas200622 * 1746537f381Sas200622 * IMPORTANT: The original sid is modified in place. This function assumes 1756537f381Sas200622 * given SID is in valid string format. 176da6c28aaSamw */ 1776537f381Sas200622 int 1786537f381Sas200622 smb_sid_splitstr(char *strsid, uint32_t *rid) 179da6c28aaSamw { 1806537f381Sas200622 char *p; 181da6c28aaSamw 1826537f381Sas200622 if ((p = strrchr(strsid, '-')) == NULL) 1836537f381Sas200622 return (-1); 184da6c28aaSamw 1856537f381Sas200622 *p++ = '\0'; 1866537f381Sas200622 if (rid) { 1876537f381Sas200622 #ifdef _KERNEL 1886537f381Sas200622 unsigned long sua = 0; 1896537f381Sas200622 (void) ddi_strtoul(p, NULL, 10, &sua); 1906537f381Sas200622 *rid = (uint32_t)sua; 1916537f381Sas200622 #else 1926537f381Sas200622 *rid = strtoul(p, NULL, 10); 1936537f381Sas200622 #endif 1946537f381Sas200622 } 1956537f381Sas200622 196da6c28aaSamw return (0); 197da6c28aaSamw } 198da6c28aaSamw 199da6c28aaSamw /* 2006537f381Sas200622 * smb_sid_cmp 201da6c28aaSamw * 202da6c28aaSamw * Compare two SIDs and return a boolean result. The checks are ordered 203da6c28aaSamw * such that components that are more likely to differ are checked 204da6c28aaSamw * first. For example, after checking that the SIDs contain the same 2056537f381Sas200622 * sid_subauthcnt, we check the sub-authorities in reverse order because 206da6c28aaSamw * the RID is the most likely differentiator between two SIDs, i.e. 207da6c28aaSamw * they are probably going to be in the same domain. 208da6c28aaSamw */ 2096537f381Sas200622 boolean_t 2106537f381Sas200622 smb_sid_cmp(smb_sid_t *sid1, smb_sid_t *sid2) 211da6c28aaSamw { 212da6c28aaSamw int i; 213da6c28aaSamw 2146537f381Sas200622 if (sid1 == NULL || sid2 == NULL) 2156537f381Sas200622 return (B_FALSE); 216da6c28aaSamw 2176537f381Sas200622 if (sid1->sid_subauthcnt != sid2->sid_subauthcnt || 2186537f381Sas200622 sid1->sid_revision != sid2->sid_revision) 2196537f381Sas200622 return (B_FALSE); 220da6c28aaSamw 2216537f381Sas200622 for (i = sid1->sid_subauthcnt - 1; i >= 0; --i) 2226537f381Sas200622 if (sid1->sid_subauth[i] != sid2->sid_subauth[i]) 2236537f381Sas200622 return (B_FALSE); 224da6c28aaSamw 2256537f381Sas200622 if (bcmp(&sid1->sid_authority, &sid2->sid_authority, NT_SID_AUTH_MAX)) 2266537f381Sas200622 return (B_FALSE); 227da6c28aaSamw 2286537f381Sas200622 return (B_TRUE); 229da6c28aaSamw } 230da6c28aaSamw 231da6c28aaSamw /* 2326537f381Sas200622 * smb_sid_indomain 233da6c28aaSamw * 234da6c28aaSamw * Check if given SID is in given domain. 235da6c28aaSamw */ 2366537f381Sas200622 boolean_t 2376537f381Sas200622 smb_sid_indomain(smb_sid_t *domain_sid, smb_sid_t *sid) 238da6c28aaSamw { 239da6c28aaSamw int i; 240da6c28aaSamw 2416537f381Sas200622 if (sid == NULL || domain_sid == NULL) 2426537f381Sas200622 return (B_FALSE); 243da6c28aaSamw 2446537f381Sas200622 if (domain_sid->sid_revision != sid->sid_revision || 2456537f381Sas200622 sid->sid_subauthcnt < domain_sid->sid_subauthcnt) 2466537f381Sas200622 return (B_FALSE); 247da6c28aaSamw 2486537f381Sas200622 for (i = domain_sid->sid_subauthcnt - 1; i >= 0; --i) 2496537f381Sas200622 if (domain_sid->sid_subauth[i] != sid->sid_subauth[i]) 2506537f381Sas200622 return (B_FALSE); 251da6c28aaSamw 2526537f381Sas200622 if (bcmp(&domain_sid->sid_authority, &sid->sid_authority, 2536537f381Sas200622 NT_SID_AUTH_MAX)) 2546537f381Sas200622 return (B_FALSE); 255da6c28aaSamw 2566537f381Sas200622 return (B_TRUE); 257da6c28aaSamw } 258da6c28aaSamw 259da6c28aaSamw #ifndef _KERNEL 260da6c28aaSamw /* 2616537f381Sas200622 * smb_sid_islocal 262da6c28aaSamw * 2636537f381Sas200622 * Check a SID to see if it belongs to the local domain. 264da6c28aaSamw */ 2656537f381Sas200622 boolean_t 2666537f381Sas200622 smb_sid_islocal(smb_sid_t *sid) 267da6c28aaSamw { 268a0aa776eSAlan Wright smb_domain_t di; 26929bd2886SAlan Wright boolean_t islocal = B_FALSE; 27029bd2886SAlan Wright 271a0aa776eSAlan Wright if (smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) 27229bd2886SAlan Wright islocal = smb_sid_indomain(di.di_binsid, sid); 27329bd2886SAlan Wright 27429bd2886SAlan Wright return (islocal); 275da6c28aaSamw } 276da6c28aaSamw #endif /* _KERNEL */ 277da6c28aaSamw 278da6c28aaSamw /* 2796537f381Sas200622 * smb_sid_tostr 280da6c28aaSamw * 2816537f381Sas200622 * Fill in the passed buffer with the string form of the given 2826537f381Sas200622 * binary sid. 283da6c28aaSamw */ 284da6c28aaSamw void 2856537f381Sas200622 smb_sid_tostr(smb_sid_t *sid, char *strsid) 286da6c28aaSamw { 2876537f381Sas200622 char *p = strsid; 2886537f381Sas200622 int i; 289da6c28aaSamw 2906537f381Sas200622 if (sid == NULL || strsid == NULL) 291da6c28aaSamw return; 292da6c28aaSamw 2936537f381Sas200622 (void) sprintf(p, "S-%d-", sid->sid_revision); 294da6c28aaSamw while (*p) 2956537f381Sas200622 p++; 296da6c28aaSamw 297da6c28aaSamw for (i = 0; i < NT_SID_AUTH_MAX; ++i) { 2986537f381Sas200622 if (sid->sid_authority[i] != 0 || i == NT_SID_AUTH_MAX - 1) { 2996537f381Sas200622 (void) sprintf(p, "%d", sid->sid_authority[i]); 300da6c28aaSamw while (*p) 3016537f381Sas200622 p++; 302da6c28aaSamw } 303da6c28aaSamw } 304da6c28aaSamw 3056537f381Sas200622 for (i = 0; i < sid->sid_subauthcnt && i < NT_SID_SUBAUTH_MAX; ++i) { 3066537f381Sas200622 (void) sprintf(p, "-%u", sid->sid_subauth[i]); 307da6c28aaSamw while (*p) 3086537f381Sas200622 p++; 309da6c28aaSamw } 310da6c28aaSamw } 311da6c28aaSamw 312da6c28aaSamw /* 3136537f381Sas200622 * smb_sid_fromstr 314da6c28aaSamw * 315da6c28aaSamw * Converts a SID in string form to a SID structure. There are lots of 316da6c28aaSamw * simplifying assumptions in here. The memory for the SID is allocated 317da6c28aaSamw * as if it was the largest possible SID; the caller is responsible for 318da6c28aaSamw * freeing the memory when it is no longer required. We assume that the 319da6c28aaSamw * string starts with "S-1-" and that the authority is held in the last 320da6c28aaSamw * byte, which should be okay for most situations. It also assumes the 321da6c28aaSamw * sub-authorities are in decimal format. 322da6c28aaSamw * 323da6c28aaSamw * On success, a pointer to a SID is returned. Otherwise a null pointer 324da6c28aaSamw * is returned. 325da6c28aaSamw */ 3266537f381Sas200622 #ifdef _KERNEL 3276537f381Sas200622 smb_sid_t * 3286537f381Sas200622 smb_sid_fromstr(char *sidstr) 329da6c28aaSamw { 3306537f381Sas200622 smb_sid_t *sid; 3316537f381Sas200622 smb_sid_t *retsid; 332da6c28aaSamw char *p; 333da6c28aaSamw int size; 3346537f381Sas200622 uint8_t i; 3356537f381Sas200622 unsigned long sua; 336da6c28aaSamw 3376537f381Sas200622 if (sidstr == NULL) 3386537f381Sas200622 return (NULL); 339da6c28aaSamw 3406537f381Sas200622 if (strncmp(sidstr, "S-1-", 4) != 0) 3416537f381Sas200622 return (NULL); 342da6c28aaSamw 3436537f381Sas200622 size = sizeof (smb_sid_t) + (NT_SID_SUBAUTH_MAX * sizeof (uint32_t)); 3446537f381Sas200622 sid = kmem_zalloc(size, KM_SLEEP); 345da6c28aaSamw 3466537f381Sas200622 sid->sid_revision = NT_SID_REVISION; 347da6c28aaSamw sua = 0; 3486537f381Sas200622 (void) ddi_strtoul(&sidstr[4], 0, 10, &sua); 3496537f381Sas200622 sid->sid_authority[5] = (uint8_t)sua; 350da6c28aaSamw 351da6c28aaSamw for (i = 0, p = &sidstr[5]; i < NT_SID_SUBAUTH_MAX && *p; ++i) { 352da6c28aaSamw while (*p && *p == '-') 353da6c28aaSamw ++p; 354da6c28aaSamw 355da6c28aaSamw if (*p < '0' || *p > '9') { 3566537f381Sas200622 kmem_free(sid, size); 3576537f381Sas200622 return (NULL); 358da6c28aaSamw } 359da6c28aaSamw 360da6c28aaSamw sua = 0; 3616537f381Sas200622 (void) ddi_strtoul(p, 0, 10, &sua); 3626537f381Sas200622 sid->sid_subauth[i] = (uint32_t)sua; 363da6c28aaSamw 364da6c28aaSamw while (*p && *p != '-') 365da6c28aaSamw ++p; 366da6c28aaSamw } 367da6c28aaSamw 3686537f381Sas200622 sid->sid_subauthcnt = i; 3696537f381Sas200622 retsid = smb_sid_dup(sid); 3706537f381Sas200622 kmem_free(sid, size); 3716537f381Sas200622 3726537f381Sas200622 return (retsid); 3736537f381Sas200622 } 3746537f381Sas200622 #else /* _KERNEL */ 3756537f381Sas200622 smb_sid_t * 3766537f381Sas200622 smb_sid_fromstr(char *sidstr) 3776537f381Sas200622 { 3786537f381Sas200622 smb_sid_t *sid; 3796537f381Sas200622 char *p; 3806537f381Sas200622 int size; 3816537f381Sas200622 uint8_t i; 3826537f381Sas200622 3836537f381Sas200622 if (sidstr == NULL) 3846537f381Sas200622 return (NULL); 3856537f381Sas200622 3866537f381Sas200622 if (strncmp(sidstr, "S-1-", 4) != 0) 3876537f381Sas200622 return (NULL); 3886537f381Sas200622 3896537f381Sas200622 size = sizeof (smb_sid_t) + (NT_SID_SUBAUTH_MAX * sizeof (uint32_t)); 3906537f381Sas200622 3916537f381Sas200622 if ((sid = malloc(size)) == NULL) 3926537f381Sas200622 return (NULL); 3936537f381Sas200622 3946537f381Sas200622 bzero(sid, size); 3956537f381Sas200622 sid->sid_revision = NT_SID_REVISION; 3966537f381Sas200622 sid->sid_authority[5] = atoi(&sidstr[4]); 3976537f381Sas200622 3986537f381Sas200622 for (i = 0, p = &sidstr[5]; i < NT_SID_SUBAUTH_MAX && *p; ++i) { 3996537f381Sas200622 while (*p && *p == '-') 4006537f381Sas200622 ++p; 4016537f381Sas200622 4026537f381Sas200622 if (*p < '0' || *p > '9') { 4036537f381Sas200622 free(sid); 4046537f381Sas200622 return (NULL); 405da6c28aaSamw } 406da6c28aaSamw 4076537f381Sas200622 sid->sid_subauth[i] = strtoul(p, NULL, 10); 4086537f381Sas200622 4096537f381Sas200622 while (*p && *p != '-') 4106537f381Sas200622 ++p; 4116537f381Sas200622 } 4126537f381Sas200622 4136537f381Sas200622 sid->sid_subauthcnt = i; 4146537f381Sas200622 return (sid); 4156537f381Sas200622 } 4166537f381Sas200622 #endif /* _KERNEL */ 417da6c28aaSamw 418da6c28aaSamw /* 4196537f381Sas200622 * smb_sid_type2str 420da6c28aaSamw * 421da6c28aaSamw * Returns the text name for a SID_NAME_USE value. The SID_NAME_USE 422da6c28aaSamw * provides the context for a SID, i.e. the type of resource to which 423da6c28aaSamw * it refers. 424da6c28aaSamw */ 425da6c28aaSamw char * 4266537f381Sas200622 smb_sid_type2str(uint16_t snu_id) 427da6c28aaSamw { 428da6c28aaSamw static char *snu_name[] = { 429da6c28aaSamw "SidTypeSidPrefix", 430da6c28aaSamw "SidTypeUser", 431da6c28aaSamw "SidTypeGroup", 432da6c28aaSamw "SidTypeDomain", 433da6c28aaSamw "SidTypeAlias", 434da6c28aaSamw "SidTypeWellKnownGroup", 435da6c28aaSamw "SidTypeDeletedAccount", 436da6c28aaSamw "SidTypeInvalid", 437*fe1c642dSBill Krier "SidTypeUnknown", 438*fe1c642dSBill Krier "SidTypeComputer", 439*fe1c642dSBill Krier "SidTypeLabel" 440da6c28aaSamw }; 441da6c28aaSamw 442da6c28aaSamw if (snu_id < ((sizeof (snu_name)/sizeof (snu_name[0])))) 443da6c28aaSamw return (snu_name[snu_id]); 4446537f381Sas200622 445da6c28aaSamw return (snu_name[SidTypeUnknown]); 446da6c28aaSamw } 4476537f381Sas200622 4486537f381Sas200622 static smb_sid_t * 4496537f381Sas200622 smb_sid_alloc(size_t size) 4506537f381Sas200622 { 4516537f381Sas200622 smb_sid_t *sid; 4526537f381Sas200622 #ifdef _KERNEL 4536537f381Sas200622 sid = kmem_alloc(size, KM_SLEEP); 4546537f381Sas200622 #else 4556537f381Sas200622 sid = malloc(size); 4566537f381Sas200622 #endif 4576537f381Sas200622 return (sid); 458da6c28aaSamw } 459da6c28aaSamw 4606537f381Sas200622 void 4616537f381Sas200622 smb_sid_free(smb_sid_t *sid) 462da6c28aaSamw { 4636537f381Sas200622 #ifdef _KERNEL 4646537f381Sas200622 if (sid == NULL) 4656537f381Sas200622 return; 466da6c28aaSamw 4676537f381Sas200622 kmem_free(sid, smb_sid_len(sid)); 4686537f381Sas200622 #else 4696537f381Sas200622 free(sid); 4706537f381Sas200622 #endif 471da6c28aaSamw } 4727f667e74Sjose borrego 4737f667e74Sjose borrego #ifndef _KERNEL 4747f667e74Sjose borrego void 4757f667e74Sjose borrego smb_ids_free(smb_ids_t *ids) 4767f667e74Sjose borrego { 4777f667e74Sjose borrego smb_id_t *id; 4787f667e74Sjose borrego int i; 4797f667e74Sjose borrego 4807f667e74Sjose borrego if ((ids != NULL) && (ids->i_ids != NULL)) { 4817f667e74Sjose borrego id = ids->i_ids; 4827f667e74Sjose borrego for (i = 0; i < ids->i_cnt; i++, id++) 4837f667e74Sjose borrego smb_sid_free(id->i_sid); 4847f667e74Sjose borrego 4857f667e74Sjose borrego free(ids->i_ids); 4867f667e74Sjose borrego } 4877f667e74Sjose borrego } 4887f667e74Sjose borrego #endif 489