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 /* 22*148c5f43SAlan Wright * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23da6c28aaSamw */ 24da6c28aaSamw 25da6c28aaSamw #ifndef _KERNEL 26da6c28aaSamw #include <stdio.h> 27da6c28aaSamw #include <strings.h> 28da6c28aaSamw #include <stdlib.h> 29da6c28aaSamw #include <syslog.h> 30da6c28aaSamw #include <smbsrv/libsmb.h> 31da6c28aaSamw #else /* _KERNEL */ 32da6c28aaSamw #include <sys/types.h> 33da6c28aaSamw #include <sys/sunddi.h> 34da6c28aaSamw #endif /* _KERNEL */ 35da6c28aaSamw 366537f381Sas200622 #include <smbsrv/smb_sid.h> 37da6c28aaSamw 386537f381Sas200622 static smb_sid_t *smb_sid_alloc(size_t); 39da6c28aaSamw 40da6c28aaSamw /* 416537f381Sas200622 * smb_sid_isvalid 42da6c28aaSamw * 436537f381Sas200622 * Performs a minimal SID validation. 44da6c28aaSamw */ 456537f381Sas200622 boolean_t 466537f381Sas200622 smb_sid_isvalid(smb_sid_t *sid) 47da6c28aaSamw { 486537f381Sas200622 if (sid == NULL) 496537f381Sas200622 return (B_FALSE); 50da6c28aaSamw 516537f381Sas200622 return ((sid->sid_revision == NT_SID_REVISION) && 526537f381Sas200622 (sid->sid_subauthcnt < NT_SID_SUBAUTH_MAX)); 53da6c28aaSamw } 54da6c28aaSamw 55da6c28aaSamw /* 566537f381Sas200622 * smb_sid_len 57da6c28aaSamw * 58da6c28aaSamw * Returns the number of bytes required to hold the sid. 59da6c28aaSamw */ 60da6c28aaSamw int 616537f381Sas200622 smb_sid_len(smb_sid_t *sid) 62da6c28aaSamw { 636537f381Sas200622 if (sid == NULL) 64da6c28aaSamw return (0); 65da6c28aaSamw 666537f381Sas200622 return (sizeof (smb_sid_t) - sizeof (uint32_t) 676537f381Sas200622 + (sid->sid_subauthcnt * sizeof (uint32_t))); 68da6c28aaSamw } 69da6c28aaSamw 70da6c28aaSamw /* 716537f381Sas200622 * smb_sid_dup 72da6c28aaSamw * 736537f381Sas200622 * Make a duplicate of the specified sid. The memory for the new sid 746537f381Sas200622 * should be freed by calling smb_sid_free(). 756537f381Sas200622 * A pointer to the new sid is returned. 76da6c28aaSamw */ 776537f381Sas200622 smb_sid_t * 786537f381Sas200622 smb_sid_dup(smb_sid_t *sid) 79da6c28aaSamw { 806537f381Sas200622 smb_sid_t *new_sid; 81da6c28aaSamw int size; 82da6c28aaSamw 836537f381Sas200622 if (sid == NULL) 846537f381Sas200622 return (NULL); 85da6c28aaSamw 866537f381Sas200622 size = smb_sid_len(sid); 876537f381Sas200622 if ((new_sid = smb_sid_alloc(size)) == NULL) 886537f381Sas200622 return (NULL); 89da6c28aaSamw 906537f381Sas200622 bcopy(sid, new_sid, size); 91da6c28aaSamw return (new_sid); 92da6c28aaSamw } 93da6c28aaSamw 94da6c28aaSamw 95da6c28aaSamw /* 966537f381Sas200622 * smb_sid_splice 97da6c28aaSamw * 986537f381Sas200622 * Make a full sid from a domain sid and a relative id (rid). 996537f381Sas200622 * The memory for the result sid should be freed by calling 1006537f381Sas200622 * smb_sid_free(). A pointer to the new sid is returned. 101da6c28aaSamw */ 1026537f381Sas200622 smb_sid_t * 1036537f381Sas200622 smb_sid_splice(smb_sid_t *domain_sid, uint32_t rid) 104da6c28aaSamw { 1056537f381Sas200622 smb_sid_t *sid; 106da6c28aaSamw int size; 107da6c28aaSamw 1086537f381Sas200622 if (domain_sid == NULL) 1096537f381Sas200622 return (NULL); 110da6c28aaSamw 1116537f381Sas200622 size = smb_sid_len(domain_sid); 1126537f381Sas200622 if ((sid = smb_sid_alloc(size + sizeof (rid))) == NULL) 1136537f381Sas200622 return (NULL); 114da6c28aaSamw 1156537f381Sas200622 bcopy(domain_sid, sid, size); 116da6c28aaSamw 1176537f381Sas200622 sid->sid_subauth[domain_sid->sid_subauthcnt] = rid; 1186537f381Sas200622 ++sid->sid_subauthcnt; 119da6c28aaSamw 120da6c28aaSamw return (sid); 121da6c28aaSamw } 122da6c28aaSamw 123da6c28aaSamw /* 1246537f381Sas200622 * smb_sid_getrid 125da6c28aaSamw * 1266537f381Sas200622 * Return the Relative Id (RID) of the specified SID. It is the 127da6c28aaSamw * caller's responsibility to ensure that this is an appropriate SID. 128da6c28aaSamw * All we do here is return the last sub-authority from the SID. 129da6c28aaSamw */ 130da6c28aaSamw int 1316537f381Sas200622 smb_sid_getrid(smb_sid_t *sid, uint32_t *rid) 132da6c28aaSamw { 1336537f381Sas200622 if (!smb_sid_isvalid(sid) || (rid == NULL) || 1346537f381Sas200622 (sid->sid_subauthcnt == 0)) 135da6c28aaSamw return (-1); 136da6c28aaSamw 1376537f381Sas200622 *rid = sid->sid_subauth[sid->sid_subauthcnt - 1]; 138da6c28aaSamw return (0); 139da6c28aaSamw } 140da6c28aaSamw 141da6c28aaSamw /* 1426537f381Sas200622 * smb_sid_split 143da6c28aaSamw * 1446537f381Sas200622 * Take a full sid and split it into a domain sid and a relative id (rid). 1457f667e74Sjose borrego * The domain SID is allocated and a pointer to it will be returned. The 1467f667e74Sjose borrego * RID value is passed back in 'rid' arg if it's not NULL. The allocated 1477f667e74Sjose borrego * memory for the domain SID must be freed by caller. 148da6c28aaSamw */ 1497f667e74Sjose borrego smb_sid_t * 1506537f381Sas200622 smb_sid_split(smb_sid_t *sid, uint32_t *rid) 151da6c28aaSamw { 1527f667e74Sjose borrego smb_sid_t *domsid; 153da6c28aaSamw 1547f667e74Sjose borrego if (!smb_sid_isvalid(sid) || (sid->sid_subauthcnt == 0)) 1557f667e74Sjose borrego return (NULL); 1567f667e74Sjose borrego 1577f667e74Sjose borrego if ((domsid = smb_sid_dup(sid)) == NULL) 1587f667e74Sjose borrego return (NULL); 1597f667e74Sjose borrego 1607f667e74Sjose borrego --domsid->sid_subauthcnt; 161da6c28aaSamw if (rid) 1627f667e74Sjose borrego *rid = domsid->sid_subauth[domsid->sid_subauthcnt]; 1637f667e74Sjose borrego 1647f667e74Sjose borrego return (domsid); 165da6c28aaSamw } 166da6c28aaSamw 167da6c28aaSamw /* 1686537f381Sas200622 * smb_sid_splitstr 169da6c28aaSamw * 1706537f381Sas200622 * Takes a full sid in string form and split it into a domain sid and a 1716537f381Sas200622 * relative id (rid). 1726537f381Sas200622 * 1736537f381Sas200622 * IMPORTANT: The original sid is modified in place. This function assumes 1746537f381Sas200622 * given SID is in valid string format. 175da6c28aaSamw */ 1766537f381Sas200622 int 1776537f381Sas200622 smb_sid_splitstr(char *strsid, uint32_t *rid) 178da6c28aaSamw { 1796537f381Sas200622 char *p; 180da6c28aaSamw 1816537f381Sas200622 if ((p = strrchr(strsid, '-')) == NULL) 1826537f381Sas200622 return (-1); 183da6c28aaSamw 1846537f381Sas200622 *p++ = '\0'; 1856537f381Sas200622 if (rid) { 1866537f381Sas200622 #ifdef _KERNEL 1876537f381Sas200622 unsigned long sua = 0; 1886537f381Sas200622 (void) ddi_strtoul(p, NULL, 10, &sua); 1896537f381Sas200622 *rid = (uint32_t)sua; 1906537f381Sas200622 #else 1916537f381Sas200622 *rid = strtoul(p, NULL, 10); 1926537f381Sas200622 #endif 1936537f381Sas200622 } 1946537f381Sas200622 195da6c28aaSamw return (0); 196da6c28aaSamw } 197da6c28aaSamw 198da6c28aaSamw /* 1996537f381Sas200622 * smb_sid_cmp 200da6c28aaSamw * 201da6c28aaSamw * Compare two SIDs and return a boolean result. The checks are ordered 202da6c28aaSamw * such that components that are more likely to differ are checked 203da6c28aaSamw * first. For example, after checking that the SIDs contain the same 2046537f381Sas200622 * sid_subauthcnt, we check the sub-authorities in reverse order because 205da6c28aaSamw * the RID is the most likely differentiator between two SIDs, i.e. 206da6c28aaSamw * they are probably going to be in the same domain. 207da6c28aaSamw */ 2086537f381Sas200622 boolean_t 2096537f381Sas200622 smb_sid_cmp(smb_sid_t *sid1, smb_sid_t *sid2) 210da6c28aaSamw { 211da6c28aaSamw int i; 212da6c28aaSamw 2136537f381Sas200622 if (sid1 == NULL || sid2 == NULL) 2146537f381Sas200622 return (B_FALSE); 215da6c28aaSamw 2166537f381Sas200622 if (sid1->sid_subauthcnt != sid2->sid_subauthcnt || 2176537f381Sas200622 sid1->sid_revision != sid2->sid_revision) 2186537f381Sas200622 return (B_FALSE); 219da6c28aaSamw 2206537f381Sas200622 for (i = sid1->sid_subauthcnt - 1; i >= 0; --i) 2216537f381Sas200622 if (sid1->sid_subauth[i] != sid2->sid_subauth[i]) 2226537f381Sas200622 return (B_FALSE); 223da6c28aaSamw 2246537f381Sas200622 if (bcmp(&sid1->sid_authority, &sid2->sid_authority, NT_SID_AUTH_MAX)) 2256537f381Sas200622 return (B_FALSE); 226da6c28aaSamw 2276537f381Sas200622 return (B_TRUE); 228da6c28aaSamw } 229da6c28aaSamw 230da6c28aaSamw /* 2316537f381Sas200622 * smb_sid_indomain 232da6c28aaSamw * 233da6c28aaSamw * Check if given SID is in given domain. 234da6c28aaSamw */ 2356537f381Sas200622 boolean_t 2366537f381Sas200622 smb_sid_indomain(smb_sid_t *domain_sid, smb_sid_t *sid) 237da6c28aaSamw { 238da6c28aaSamw int i; 239da6c28aaSamw 2406537f381Sas200622 if (sid == NULL || domain_sid == NULL) 2416537f381Sas200622 return (B_FALSE); 242da6c28aaSamw 2436537f381Sas200622 if (domain_sid->sid_revision != sid->sid_revision || 2446537f381Sas200622 sid->sid_subauthcnt < domain_sid->sid_subauthcnt) 2456537f381Sas200622 return (B_FALSE); 246da6c28aaSamw 2476537f381Sas200622 for (i = domain_sid->sid_subauthcnt - 1; i >= 0; --i) 2486537f381Sas200622 if (domain_sid->sid_subauth[i] != sid->sid_subauth[i]) 2496537f381Sas200622 return (B_FALSE); 250da6c28aaSamw 2516537f381Sas200622 if (bcmp(&domain_sid->sid_authority, &sid->sid_authority, 2526537f381Sas200622 NT_SID_AUTH_MAX)) 2536537f381Sas200622 return (B_FALSE); 254da6c28aaSamw 2556537f381Sas200622 return (B_TRUE); 256da6c28aaSamw } 257da6c28aaSamw 258da6c28aaSamw #ifndef _KERNEL 259da6c28aaSamw /* 2606537f381Sas200622 * smb_sid_islocal 261da6c28aaSamw * 2626537f381Sas200622 * Check a SID to see if it belongs to the local domain. 263da6c28aaSamw */ 2646537f381Sas200622 boolean_t 2656537f381Sas200622 smb_sid_islocal(smb_sid_t *sid) 266da6c28aaSamw { 267a0aa776eSAlan Wright smb_domain_t di; 26829bd2886SAlan Wright boolean_t islocal = B_FALSE; 26929bd2886SAlan Wright 270a0aa776eSAlan Wright if (smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) 27129bd2886SAlan Wright islocal = smb_sid_indomain(di.di_binsid, sid); 27229bd2886SAlan Wright 27329bd2886SAlan Wright return (islocal); 274da6c28aaSamw } 275da6c28aaSamw #endif /* _KERNEL */ 276da6c28aaSamw 277da6c28aaSamw /* 2786537f381Sas200622 * smb_sid_tostr 279da6c28aaSamw * 2806537f381Sas200622 * Fill in the passed buffer with the string form of the given 2816537f381Sas200622 * binary sid. 282da6c28aaSamw */ 283da6c28aaSamw void 284*148c5f43SAlan Wright smb_sid_tostr(const smb_sid_t *sid, char *strsid) 285da6c28aaSamw { 2866537f381Sas200622 char *p = strsid; 2876537f381Sas200622 int i; 288da6c28aaSamw 2896537f381Sas200622 if (sid == NULL || strsid == NULL) 290da6c28aaSamw return; 291da6c28aaSamw 2926537f381Sas200622 (void) sprintf(p, "S-%d-", sid->sid_revision); 293da6c28aaSamw while (*p) 2946537f381Sas200622 p++; 295da6c28aaSamw 296da6c28aaSamw for (i = 0; i < NT_SID_AUTH_MAX; ++i) { 2976537f381Sas200622 if (sid->sid_authority[i] != 0 || i == NT_SID_AUTH_MAX - 1) { 2986537f381Sas200622 (void) sprintf(p, "%d", sid->sid_authority[i]); 299da6c28aaSamw while (*p) 3006537f381Sas200622 p++; 301da6c28aaSamw } 302da6c28aaSamw } 303da6c28aaSamw 3046537f381Sas200622 for (i = 0; i < sid->sid_subauthcnt && i < NT_SID_SUBAUTH_MAX; ++i) { 3056537f381Sas200622 (void) sprintf(p, "-%u", sid->sid_subauth[i]); 306da6c28aaSamw while (*p) 3076537f381Sas200622 p++; 308da6c28aaSamw } 309da6c28aaSamw } 310da6c28aaSamw 311da6c28aaSamw /* 3126537f381Sas200622 * smb_sid_fromstr 313da6c28aaSamw * 314da6c28aaSamw * Converts a SID in string form to a SID structure. There are lots of 315da6c28aaSamw * simplifying assumptions in here. The memory for the SID is allocated 316da6c28aaSamw * as if it was the largest possible SID; the caller is responsible for 317da6c28aaSamw * freeing the memory when it is no longer required. We assume that the 318da6c28aaSamw * string starts with "S-1-" and that the authority is held in the last 319da6c28aaSamw * byte, which should be okay for most situations. It also assumes the 320da6c28aaSamw * sub-authorities are in decimal format. 321da6c28aaSamw * 322da6c28aaSamw * On success, a pointer to a SID is returned. Otherwise a null pointer 323da6c28aaSamw * is returned. 324da6c28aaSamw */ 3256537f381Sas200622 #ifdef _KERNEL 3266537f381Sas200622 smb_sid_t * 327*148c5f43SAlan Wright smb_sid_fromstr(const char *sidstr) 328da6c28aaSamw { 3296537f381Sas200622 smb_sid_t *sid; 3306537f381Sas200622 smb_sid_t *retsid; 331*148c5f43SAlan Wright const char *p; 332da6c28aaSamw int size; 3336537f381Sas200622 uint8_t i; 3346537f381Sas200622 unsigned long sua; 335da6c28aaSamw 3366537f381Sas200622 if (sidstr == NULL) 3376537f381Sas200622 return (NULL); 338da6c28aaSamw 3396537f381Sas200622 if (strncmp(sidstr, "S-1-", 4) != 0) 3406537f381Sas200622 return (NULL); 341da6c28aaSamw 3426537f381Sas200622 size = sizeof (smb_sid_t) + (NT_SID_SUBAUTH_MAX * sizeof (uint32_t)); 3436537f381Sas200622 sid = kmem_zalloc(size, KM_SLEEP); 344da6c28aaSamw 3456537f381Sas200622 sid->sid_revision = NT_SID_REVISION; 346da6c28aaSamw sua = 0; 3476537f381Sas200622 (void) ddi_strtoul(&sidstr[4], 0, 10, &sua); 3486537f381Sas200622 sid->sid_authority[5] = (uint8_t)sua; 349da6c28aaSamw 350da6c28aaSamw for (i = 0, p = &sidstr[5]; i < NT_SID_SUBAUTH_MAX && *p; ++i) { 351da6c28aaSamw while (*p && *p == '-') 352da6c28aaSamw ++p; 353da6c28aaSamw 354da6c28aaSamw if (*p < '0' || *p > '9') { 3556537f381Sas200622 kmem_free(sid, size); 3566537f381Sas200622 return (NULL); 357da6c28aaSamw } 358da6c28aaSamw 359da6c28aaSamw sua = 0; 3606537f381Sas200622 (void) ddi_strtoul(p, 0, 10, &sua); 3616537f381Sas200622 sid->sid_subauth[i] = (uint32_t)sua; 362da6c28aaSamw 363da6c28aaSamw while (*p && *p != '-') 364da6c28aaSamw ++p; 365da6c28aaSamw } 366da6c28aaSamw 3676537f381Sas200622 sid->sid_subauthcnt = i; 3686537f381Sas200622 retsid = smb_sid_dup(sid); 3696537f381Sas200622 kmem_free(sid, size); 3706537f381Sas200622 3716537f381Sas200622 return (retsid); 3726537f381Sas200622 } 3736537f381Sas200622 #else /* _KERNEL */ 3746537f381Sas200622 smb_sid_t * 375*148c5f43SAlan Wright smb_sid_fromstr(const char *sidstr) 3766537f381Sas200622 { 3776537f381Sas200622 smb_sid_t *sid; 378*148c5f43SAlan Wright const char *p; 3796537f381Sas200622 int size; 3806537f381Sas200622 uint8_t i; 3816537f381Sas200622 3826537f381Sas200622 if (sidstr == NULL) 3836537f381Sas200622 return (NULL); 3846537f381Sas200622 3856537f381Sas200622 if (strncmp(sidstr, "S-1-", 4) != 0) 3866537f381Sas200622 return (NULL); 3876537f381Sas200622 3886537f381Sas200622 size = sizeof (smb_sid_t) + (NT_SID_SUBAUTH_MAX * sizeof (uint32_t)); 3896537f381Sas200622 3906537f381Sas200622 if ((sid = malloc(size)) == NULL) 3916537f381Sas200622 return (NULL); 3926537f381Sas200622 3936537f381Sas200622 bzero(sid, size); 3946537f381Sas200622 sid->sid_revision = NT_SID_REVISION; 3956537f381Sas200622 sid->sid_authority[5] = atoi(&sidstr[4]); 3966537f381Sas200622 3976537f381Sas200622 for (i = 0, p = &sidstr[5]; i < NT_SID_SUBAUTH_MAX && *p; ++i) { 3986537f381Sas200622 while (*p && *p == '-') 3996537f381Sas200622 ++p; 4006537f381Sas200622 4016537f381Sas200622 if (*p < '0' || *p > '9') { 4026537f381Sas200622 free(sid); 4036537f381Sas200622 return (NULL); 404da6c28aaSamw } 405da6c28aaSamw 4066537f381Sas200622 sid->sid_subauth[i] = strtoul(p, NULL, 10); 4076537f381Sas200622 4086537f381Sas200622 while (*p && *p != '-') 4096537f381Sas200622 ++p; 4106537f381Sas200622 } 4116537f381Sas200622 4126537f381Sas200622 sid->sid_subauthcnt = i; 4136537f381Sas200622 return (sid); 4146537f381Sas200622 } 4156537f381Sas200622 #endif /* _KERNEL */ 416da6c28aaSamw 417da6c28aaSamw /* 4186537f381Sas200622 * smb_sid_type2str 419da6c28aaSamw * 420da6c28aaSamw * Returns the text name for a SID_NAME_USE value. The SID_NAME_USE 421da6c28aaSamw * provides the context for a SID, i.e. the type of resource to which 422da6c28aaSamw * it refers. 423da6c28aaSamw */ 424da6c28aaSamw char * 4256537f381Sas200622 smb_sid_type2str(uint16_t snu_id) 426da6c28aaSamw { 427da6c28aaSamw static char *snu_name[] = { 428da6c28aaSamw "SidTypeSidPrefix", 429da6c28aaSamw "SidTypeUser", 430da6c28aaSamw "SidTypeGroup", 431da6c28aaSamw "SidTypeDomain", 432da6c28aaSamw "SidTypeAlias", 433da6c28aaSamw "SidTypeWellKnownGroup", 434da6c28aaSamw "SidTypeDeletedAccount", 435da6c28aaSamw "SidTypeInvalid", 436fe1c642dSBill Krier "SidTypeUnknown", 437fe1c642dSBill Krier "SidTypeComputer", 438fe1c642dSBill Krier "SidTypeLabel" 439da6c28aaSamw }; 440da6c28aaSamw 441da6c28aaSamw if (snu_id < ((sizeof (snu_name)/sizeof (snu_name[0])))) 442da6c28aaSamw return (snu_name[snu_id]); 4436537f381Sas200622 444da6c28aaSamw return (snu_name[SidTypeUnknown]); 445da6c28aaSamw } 4466537f381Sas200622 4476537f381Sas200622 static smb_sid_t * 4486537f381Sas200622 smb_sid_alloc(size_t size) 4496537f381Sas200622 { 4506537f381Sas200622 smb_sid_t *sid; 4516537f381Sas200622 #ifdef _KERNEL 4526537f381Sas200622 sid = kmem_alloc(size, KM_SLEEP); 4536537f381Sas200622 #else 4546537f381Sas200622 sid = malloc(size); 4556537f381Sas200622 #endif 4566537f381Sas200622 return (sid); 457da6c28aaSamw } 458da6c28aaSamw 4596537f381Sas200622 void 4606537f381Sas200622 smb_sid_free(smb_sid_t *sid) 461da6c28aaSamw { 4626537f381Sas200622 #ifdef _KERNEL 4636537f381Sas200622 if (sid == NULL) 4646537f381Sas200622 return; 465da6c28aaSamw 4666537f381Sas200622 kmem_free(sid, smb_sid_len(sid)); 4676537f381Sas200622 #else 4686537f381Sas200622 free(sid); 4696537f381Sas200622 #endif 470da6c28aaSamw } 4717f667e74Sjose borrego 4727f667e74Sjose borrego #ifndef _KERNEL 4737f667e74Sjose borrego void 4747f667e74Sjose borrego smb_ids_free(smb_ids_t *ids) 4757f667e74Sjose borrego { 4767f667e74Sjose borrego smb_id_t *id; 4777f667e74Sjose borrego int i; 4787f667e74Sjose borrego 4797f667e74Sjose borrego if ((ids != NULL) && (ids->i_ids != NULL)) { 4807f667e74Sjose borrego id = ids->i_ids; 4817f667e74Sjose borrego for (i = 0; i < ids->i_cnt; i++, id++) 4827f667e74Sjose borrego smb_sid_free(id->i_sid); 4837f667e74Sjose borrego 4847f667e74Sjose borrego free(ids->i_ids); 4857f667e74Sjose borrego } 4867f667e74Sjose borrego } 4877f667e74Sjose borrego #endif 488