1*da6c28aaSamw /* 2*da6c28aaSamw * CDDL HEADER START 3*da6c28aaSamw * 4*da6c28aaSamw * The contents of this file are subject to the terms of the 5*da6c28aaSamw * Common Development and Distribution License (the "License"). 6*da6c28aaSamw * You may not use this file except in compliance with the License. 7*da6c28aaSamw * 8*da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10*da6c28aaSamw * See the License for the specific language governing permissions 11*da6c28aaSamw * and limitations under the License. 12*da6c28aaSamw * 13*da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14*da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16*da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17*da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18*da6c28aaSamw * 19*da6c28aaSamw * CDDL HEADER END 20*da6c28aaSamw */ 21*da6c28aaSamw /* 22*da6c28aaSamw * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*da6c28aaSamw * Use is subject to license terms. 24*da6c28aaSamw */ 25*da6c28aaSamw 26*da6c28aaSamw #pragma ident "%Z%%M% %I% %E% SMI" 27*da6c28aaSamw 28*da6c28aaSamw /* 29*da6c28aaSamw * NT Security Identifier (SID) library functions. 30*da6c28aaSamw */ 31*da6c28aaSamw 32*da6c28aaSamw #ifndef _KERNEL 33*da6c28aaSamw #include <stdio.h> 34*da6c28aaSamw #include <strings.h> 35*da6c28aaSamw #include <stdlib.h> 36*da6c28aaSamw #include <syslog.h> 37*da6c28aaSamw #include <smbsrv/libsmb.h> 38*da6c28aaSamw #else /* _KERNEL */ 39*da6c28aaSamw #include <sys/types.h> 40*da6c28aaSamw #include <sys/sunddi.h> 41*da6c28aaSamw #endif /* _KERNEL */ 42*da6c28aaSamw 43*da6c28aaSamw #include <smbsrv/alloc.h> 44*da6c28aaSamw #include <smbsrv/ntsid.h> 45*da6c28aaSamw #include <smbsrv/ntstatus.h> 46*da6c28aaSamw #include <smbsrv/smbinfo.h> 47*da6c28aaSamw 48*da6c28aaSamw 49*da6c28aaSamw /* 50*da6c28aaSamw * nt_sid_is_valid 51*da6c28aaSamw * 52*da6c28aaSamw * Check that a sid is valid. The checking is minimal: check the pointer 53*da6c28aaSamw * is valid and that the revision and sub-authority count is legal. 54*da6c28aaSamw * Returns 1 if the sid appears to be valid. Otherwise 0. 55*da6c28aaSamw */ 56*da6c28aaSamw int 57*da6c28aaSamw nt_sid_is_valid(nt_sid_t *sid) 58*da6c28aaSamw { 59*da6c28aaSamw if (sid == 0) 60*da6c28aaSamw return (0); 61*da6c28aaSamw 62*da6c28aaSamw return (sid->Revision == NT_SID_REVISION && 63*da6c28aaSamw sid->SubAuthCount < NT_SID_SUBAUTH_MAX) ? 1 : 0; 64*da6c28aaSamw } 65*da6c28aaSamw 66*da6c28aaSamw 67*da6c28aaSamw /* 68*da6c28aaSamw * nt_sid_length 69*da6c28aaSamw * 70*da6c28aaSamw * Returns the number of bytes required to hold the sid. 71*da6c28aaSamw */ 72*da6c28aaSamw int 73*da6c28aaSamw nt_sid_length(nt_sid_t *sid) 74*da6c28aaSamw { 75*da6c28aaSamw if (sid == 0) 76*da6c28aaSamw return (0); 77*da6c28aaSamw 78*da6c28aaSamw return (sizeof (nt_sid_t) - sizeof (DWORD) 79*da6c28aaSamw + (sid->SubAuthCount * sizeof (DWORD))); 80*da6c28aaSamw } 81*da6c28aaSamw 82*da6c28aaSamw 83*da6c28aaSamw /* 84*da6c28aaSamw * nt_sid_dup 85*da6c28aaSamw * 86*da6c28aaSamw * Make a duplicate of the specified sid. The memory for the new sid is 87*da6c28aaSamw * allocated using malloc so the caller should call free when it is no 88*da6c28aaSamw * longer required. A pointer to the new sid is returned. 89*da6c28aaSamw */ 90*da6c28aaSamw nt_sid_t * 91*da6c28aaSamw nt_sid_dup(nt_sid_t *sid) 92*da6c28aaSamw { 93*da6c28aaSamw nt_sid_t *new_sid; 94*da6c28aaSamw int size; 95*da6c28aaSamw int i; 96*da6c28aaSamw 97*da6c28aaSamw if (sid == 0) 98*da6c28aaSamw return (0); 99*da6c28aaSamw 100*da6c28aaSamw size = sizeof (nt_sid_t) 101*da6c28aaSamw + (sid->SubAuthCount * sizeof (DWORD)) 102*da6c28aaSamw + sizeof (DWORD); 103*da6c28aaSamw 104*da6c28aaSamw if ((new_sid = MEM_MALLOC("libnt", size)) == 0) 105*da6c28aaSamw return (0); 106*da6c28aaSamw 107*da6c28aaSamw (void) memcpy(new_sid, sid, sizeof (nt_sid_t)); 108*da6c28aaSamw 109*da6c28aaSamw for (i = 0; i < sid->SubAuthCount && i < NT_SID_SUBAUTH_MAX; ++i) 110*da6c28aaSamw new_sid->SubAuthority[i] = sid->SubAuthority[i]; 111*da6c28aaSamw 112*da6c28aaSamw return (new_sid); 113*da6c28aaSamw } 114*da6c28aaSamw 115*da6c28aaSamw 116*da6c28aaSamw /* 117*da6c28aaSamw * nt_sid_splice 118*da6c28aaSamw * 119*da6c28aaSamw * Make a full user sid from the domain sid and the user relative id 120*da6c28aaSamw * (rid). The memory for the new sid is allocated using malloc so the 121*da6c28aaSamw * caller should call free when it is no longer required. A pointer 122*da6c28aaSamw * to the new sid is returned. 123*da6c28aaSamw */ 124*da6c28aaSamw nt_sid_t * 125*da6c28aaSamw nt_sid_splice(nt_sid_t *domain_sid, DWORD rid) 126*da6c28aaSamw { 127*da6c28aaSamw nt_sid_t *sid; 128*da6c28aaSamw int size; 129*da6c28aaSamw int i; 130*da6c28aaSamw 131*da6c28aaSamw if (domain_sid == 0) 132*da6c28aaSamw return (0); 133*da6c28aaSamw 134*da6c28aaSamw size = sizeof (nt_sid_t) 135*da6c28aaSamw + (domain_sid->SubAuthCount * sizeof (DWORD)) 136*da6c28aaSamw + sizeof (DWORD); 137*da6c28aaSamw 138*da6c28aaSamw if ((sid = MEM_MALLOC("libnt", size)) == 0) 139*da6c28aaSamw return (0); 140*da6c28aaSamw 141*da6c28aaSamw (void) memcpy(sid, domain_sid, sizeof (nt_sid_t)); 142*da6c28aaSamw 143*da6c28aaSamw for (i = 0; i < sid->SubAuthCount && i < NT_SID_SUBAUTH_MAX; ++i) 144*da6c28aaSamw sid->SubAuthority[i] = domain_sid->SubAuthority[i]; 145*da6c28aaSamw 146*da6c28aaSamw sid->SubAuthority[i] = rid; 147*da6c28aaSamw ++sid->SubAuthCount; 148*da6c28aaSamw return (sid); 149*da6c28aaSamw } 150*da6c28aaSamw 151*da6c28aaSamw 152*da6c28aaSamw /* 153*da6c28aaSamw * nt_sid_get_rid 154*da6c28aaSamw * 155*da6c28aaSamw * Return the Relative Id (RID) from the specified SID. It is the 156*da6c28aaSamw * caller's responsibility to ensure that this is an appropriate SID. 157*da6c28aaSamw * All we do here is return the last sub-authority from the SID. 158*da6c28aaSamw */ 159*da6c28aaSamw int 160*da6c28aaSamw nt_sid_get_rid(nt_sid_t *sid, DWORD *rid) 161*da6c28aaSamw { 162*da6c28aaSamw if (!nt_sid_is_valid(sid)) 163*da6c28aaSamw return (-1); 164*da6c28aaSamw 165*da6c28aaSamw if (sid->SubAuthCount == 0) { 166*da6c28aaSamw return (-1); 167*da6c28aaSamw } 168*da6c28aaSamw 169*da6c28aaSamw if (rid) 170*da6c28aaSamw *rid = sid->SubAuthority[sid->SubAuthCount - 1]; 171*da6c28aaSamw return (0); 172*da6c28aaSamw } 173*da6c28aaSamw 174*da6c28aaSamw 175*da6c28aaSamw /* 176*da6c28aaSamw * nt_sid_split 177*da6c28aaSamw * 178*da6c28aaSamw * Take a full user sid and split it into the domain sid and the user 179*da6c28aaSamw * relative id (rid). The original sid is modified in place - use 180*da6c28aaSamw * nt_sid_dup before calling this function to preserve the original SID. 181*da6c28aaSamw */ 182*da6c28aaSamw int 183*da6c28aaSamw nt_sid_split(nt_sid_t *sid, DWORD *rid) 184*da6c28aaSamw { 185*da6c28aaSamw if (!nt_sid_is_valid(sid)) { 186*da6c28aaSamw return (-1); 187*da6c28aaSamw } 188*da6c28aaSamw 189*da6c28aaSamw if (sid->SubAuthCount == 0) { 190*da6c28aaSamw return (-1); 191*da6c28aaSamw } 192*da6c28aaSamw 193*da6c28aaSamw --sid->SubAuthCount; 194*da6c28aaSamw if (rid) 195*da6c28aaSamw *rid = sid->SubAuthority[sid->SubAuthCount]; 196*da6c28aaSamw return (0); 197*da6c28aaSamw } 198*da6c28aaSamw 199*da6c28aaSamw 200*da6c28aaSamw /* 201*da6c28aaSamw * nt_sid_gen_null_sid 202*da6c28aaSamw * 203*da6c28aaSamw * This function allocates a SID structure and initializes it as the 204*da6c28aaSamw * well-known Null SID (S-1-0-0). A pointer to the SID is returned. 205*da6c28aaSamw * As the memory for this structure is obtained via malloc, it is the 206*da6c28aaSamw * caller's responsibility to free the memory when it is no longer 207*da6c28aaSamw * required. If malloc fails, a null pointer is returned. 208*da6c28aaSamw */ 209*da6c28aaSamw nt_sid_t * 210*da6c28aaSamw nt_sid_gen_null_sid(void) 211*da6c28aaSamw { 212*da6c28aaSamw nt_sid_t *sid; 213*da6c28aaSamw int size; 214*da6c28aaSamw 215*da6c28aaSamw size = sizeof (nt_sid_t) + sizeof (DWORD); 216*da6c28aaSamw 217*da6c28aaSamw if ((sid = MEM_MALLOC("libnt", size)) == 0) { 218*da6c28aaSamw return (0); 219*da6c28aaSamw } 220*da6c28aaSamw 221*da6c28aaSamw sid->Revision = 1; 222*da6c28aaSamw sid->SubAuthCount = 1; 223*da6c28aaSamw return (sid); 224*da6c28aaSamw } 225*da6c28aaSamw 226*da6c28aaSamw 227*da6c28aaSamw /* 228*da6c28aaSamw * nt_sid_is_equal 229*da6c28aaSamw * 230*da6c28aaSamw * Compare two SIDs and return a boolean result. The checks are ordered 231*da6c28aaSamw * such that components that are more likely to differ are checked 232*da6c28aaSamw * first. For example, after checking that the SIDs contain the same 233*da6c28aaSamw * SubAuthCount, we check the sub-authorities in reverse order because 234*da6c28aaSamw * the RID is the most likely differentiator between two SIDs, i.e. 235*da6c28aaSamw * they are probably going to be in the same domain. 236*da6c28aaSamw * 237*da6c28aaSamw * Returns 1 if the SIDs are equal. Otherwise returns 0. 238*da6c28aaSamw */ 239*da6c28aaSamw int 240*da6c28aaSamw nt_sid_is_equal(nt_sid_t *sid1, nt_sid_t *sid2) 241*da6c28aaSamw { 242*da6c28aaSamw int i; 243*da6c28aaSamw 244*da6c28aaSamw if (sid1 == 0 || sid2 == 0) 245*da6c28aaSamw return (0); 246*da6c28aaSamw 247*da6c28aaSamw if (sid1->SubAuthCount != sid2->SubAuthCount || 248*da6c28aaSamw sid1->Revision != sid2->Revision) 249*da6c28aaSamw return (0); 250*da6c28aaSamw 251*da6c28aaSamw for (i = sid1->SubAuthCount - 1; i >= 0; --i) 252*da6c28aaSamw if (sid1->SubAuthority[i] != sid2->SubAuthority[i]) 253*da6c28aaSamw return (0); 254*da6c28aaSamw 255*da6c28aaSamw if (bcmp(&sid1->Authority, &sid2->Authority, NT_SID_AUTH_MAX)) 256*da6c28aaSamw return (0); 257*da6c28aaSamw 258*da6c28aaSamw return (1); 259*da6c28aaSamw } 260*da6c28aaSamw 261*da6c28aaSamw /* 262*da6c28aaSamw * nt_sid_is_indomain 263*da6c28aaSamw * 264*da6c28aaSamw * Check if given SID is in given domain. 265*da6c28aaSamw * Returns 1 on success. Otherwise returns 0. 266*da6c28aaSamw */ 267*da6c28aaSamw int 268*da6c28aaSamw nt_sid_is_indomain(nt_sid_t *domain_sid, nt_sid_t *sid) 269*da6c28aaSamw { 270*da6c28aaSamw int i; 271*da6c28aaSamw 272*da6c28aaSamw if (sid == 0 || domain_sid == 0) { 273*da6c28aaSamw return (0); 274*da6c28aaSamw } 275*da6c28aaSamw 276*da6c28aaSamw if (domain_sid->Revision != sid->Revision || 277*da6c28aaSamw sid->SubAuthCount < domain_sid->SubAuthCount) 278*da6c28aaSamw return (0); 279*da6c28aaSamw 280*da6c28aaSamw for (i = domain_sid->SubAuthCount - 1; i >= 0; --i) 281*da6c28aaSamw if (domain_sid->SubAuthority[i] != sid->SubAuthority[i]) 282*da6c28aaSamw return (0); 283*da6c28aaSamw 284*da6c28aaSamw if (bcmp(&domain_sid->Authority, &sid->Authority, NT_SID_AUTH_MAX)) 285*da6c28aaSamw return (0); 286*da6c28aaSamw 287*da6c28aaSamw return (1); 288*da6c28aaSamw } 289*da6c28aaSamw 290*da6c28aaSamw #ifndef _KERNEL 291*da6c28aaSamw /* 292*da6c28aaSamw * nt_sid_is_local 293*da6c28aaSamw * 294*da6c28aaSamw * Check a SID to see if it belongs to the local domain. This is almost 295*da6c28aaSamw * the same as checking that two SIDs are equal except that we don't 296*da6c28aaSamw * care if the specified SID contains extra sub-authorities. We're only 297*da6c28aaSamw * interested in the domain part. 298*da6c28aaSamw * 299*da6c28aaSamw * Returns 1 if the SIDs are equal. Otherwise returns 0. 300*da6c28aaSamw */ 301*da6c28aaSamw int 302*da6c28aaSamw nt_sid_is_local(nt_sid_t *sid) 303*da6c28aaSamw { 304*da6c28aaSamw nt_sid_t *local_sid; 305*da6c28aaSamw 306*da6c28aaSamw local_sid = nt_domain_local_sid(); 307*da6c28aaSamw return (nt_sid_is_indomain(local_sid, sid)); 308*da6c28aaSamw } 309*da6c28aaSamw 310*da6c28aaSamw /* 311*da6c28aaSamw * nt_sid_is_builtin 312*da6c28aaSamw * 313*da6c28aaSamw * Check a SID to see if it belongs to the builtin domain. 314*da6c28aaSamw * Returns 1 if the SID is a builtin SID. Otherwise returns 0. 315*da6c28aaSamw */ 316*da6c28aaSamw int 317*da6c28aaSamw nt_sid_is_builtin(nt_sid_t *sid) 318*da6c28aaSamw { 319*da6c28aaSamw nt_domain_t *domain; 320*da6c28aaSamw 321*da6c28aaSamw domain = nt_domain_lookupbytype(NT_DOMAIN_BUILTIN); 322*da6c28aaSamw if (domain == 0) 323*da6c28aaSamw return (0); 324*da6c28aaSamw return (nt_sid_is_indomain(domain->sid, sid)); 325*da6c28aaSamw } 326*da6c28aaSamw #endif /* _KERNEL */ 327*da6c28aaSamw 328*da6c28aaSamw /* 329*da6c28aaSamw * nt_sid_is_domain_equal 330*da6c28aaSamw * 331*da6c28aaSamw * Compare two SIDs's domain and return a boolean result. 332*da6c28aaSamw * 333*da6c28aaSamw * Returns 1 if the domain SID are the same. Otherwise returns 0. 334*da6c28aaSamw */ 335*da6c28aaSamw int 336*da6c28aaSamw nt_sid_is_domain_equal(nt_sid_t *pSid1, nt_sid_t *pSid2) 337*da6c28aaSamw { 338*da6c28aaSamw int i, n; 339*da6c28aaSamw 340*da6c28aaSamw if (pSid1->Revision != pSid2->Revision) 341*da6c28aaSamw return (0); 342*da6c28aaSamw 343*da6c28aaSamw if (pSid1->SubAuthCount != pSid2->SubAuthCount) 344*da6c28aaSamw return (0); 345*da6c28aaSamw 346*da6c28aaSamw if (bcmp(pSid1->Authority, pSid2->Authority, NT_SID_AUTH_MAX) != 0) 347*da6c28aaSamw return (0); 348*da6c28aaSamw 349*da6c28aaSamw n = pSid1->SubAuthCount; 350*da6c28aaSamw 351*da6c28aaSamw n -= 1; /* don't compare last SubAuthority[] (aka RID) */ 352*da6c28aaSamw 353*da6c28aaSamw for (i = 0; i < n; i++) 354*da6c28aaSamw if (pSid1->SubAuthority[i] != pSid2->SubAuthority[i]) 355*da6c28aaSamw return (0); 356*da6c28aaSamw 357*da6c28aaSamw return (1); 358*da6c28aaSamw } 359*da6c28aaSamw 360*da6c28aaSamw /* 361*da6c28aaSamw * nt_sid_logf 362*da6c28aaSamw * 363*da6c28aaSamw * Format a sid and write it to the system log. See nt_sid_format 364*da6c28aaSamw * for format information. 365*da6c28aaSamw */ 366*da6c28aaSamw void 367*da6c28aaSamw nt_sid_logf(nt_sid_t *sid) 368*da6c28aaSamw { 369*da6c28aaSamw char *s; 370*da6c28aaSamw 371*da6c28aaSamw if ((s = nt_sid_format(sid)) == 0) 372*da6c28aaSamw return; 373*da6c28aaSamw 374*da6c28aaSamw MEM_FREE("libnt", s); 375*da6c28aaSamw } 376*da6c28aaSamw 377*da6c28aaSamw 378*da6c28aaSamw /* 379*da6c28aaSamw * nt_sid_format 380*da6c28aaSamw * 381*da6c28aaSamw * Format a sid and return it as a string. The memory for the string is 382*da6c28aaSamw * allocated using malloc so the caller should call free when it is no 383*da6c28aaSamw * longer required. A pointer to the string is returned. 384*da6c28aaSamw */ 385*da6c28aaSamw char * 386*da6c28aaSamw nt_sid_format(nt_sid_t *sid) 387*da6c28aaSamw { 388*da6c28aaSamw int i; 389*da6c28aaSamw char *fmtbuf; 390*da6c28aaSamw char *p; 391*da6c28aaSamw 392*da6c28aaSamw if (sid == 0) 393*da6c28aaSamw return (0); 394*da6c28aaSamw 395*da6c28aaSamw if ((fmtbuf = MEM_MALLOC("libnt", NT_SID_FMTBUF_SIZE)) == 0) 396*da6c28aaSamw return (0); 397*da6c28aaSamw 398*da6c28aaSamw p = fmtbuf; 399*da6c28aaSamw (void) sprintf(p, "S-%d-", sid->Revision); 400*da6c28aaSamw while (*p) 401*da6c28aaSamw ++p; 402*da6c28aaSamw 403*da6c28aaSamw for (i = 0; i < NT_SID_AUTH_MAX; ++i) { 404*da6c28aaSamw if (sid->Authority[i] != 0 || i == NT_SID_AUTH_MAX - 1) { 405*da6c28aaSamw (void) sprintf(p, "%d", sid->Authority[i]); 406*da6c28aaSamw while (*p) 407*da6c28aaSamw ++p; 408*da6c28aaSamw } 409*da6c28aaSamw } 410*da6c28aaSamw 411*da6c28aaSamw for (i = 0; i < sid->SubAuthCount && i < NT_SID_SUBAUTH_MAX; ++i) { 412*da6c28aaSamw (void) sprintf(p, "-%u", sid->SubAuthority[i]); 413*da6c28aaSamw while (*p) 414*da6c28aaSamw ++p; 415*da6c28aaSamw } 416*da6c28aaSamw 417*da6c28aaSamw return (fmtbuf); 418*da6c28aaSamw } 419*da6c28aaSamw 420*da6c28aaSamw /* 421*da6c28aaSamw * nt_sid_format2 422*da6c28aaSamw * 423*da6c28aaSamw * Format a sid and return it in the passed buffer. 424*da6c28aaSamw */ 425*da6c28aaSamw void 426*da6c28aaSamw nt_sid_format2(nt_sid_t *sid, char *fmtbuf) 427*da6c28aaSamw { 428*da6c28aaSamw int i; 429*da6c28aaSamw char *p; 430*da6c28aaSamw 431*da6c28aaSamw if (sid == 0 || fmtbuf == 0) 432*da6c28aaSamw return; 433*da6c28aaSamw 434*da6c28aaSamw p = fmtbuf; 435*da6c28aaSamw (void) sprintf(p, "S-%d-", sid->Revision); 436*da6c28aaSamw while (*p) 437*da6c28aaSamw ++p; 438*da6c28aaSamw 439*da6c28aaSamw for (i = 0; i < NT_SID_AUTH_MAX; ++i) { 440*da6c28aaSamw if (sid->Authority[i] != 0 || i == NT_SID_AUTH_MAX - 1) { 441*da6c28aaSamw (void) sprintf(p, "%d", sid->Authority[i]); 442*da6c28aaSamw while (*p) 443*da6c28aaSamw ++p; 444*da6c28aaSamw } 445*da6c28aaSamw } 446*da6c28aaSamw 447*da6c28aaSamw for (i = 0; i < sid->SubAuthCount && i < NT_SID_SUBAUTH_MAX; ++i) { 448*da6c28aaSamw (void) sprintf(p, "-%u", sid->SubAuthority[i]); 449*da6c28aaSamw while (*p) 450*da6c28aaSamw ++p; 451*da6c28aaSamw } 452*da6c28aaSamw } 453*da6c28aaSamw 454*da6c28aaSamw /* 455*da6c28aaSamw * nt_sid_strtosid 456*da6c28aaSamw * 457*da6c28aaSamw * Converts a SID in string form to a SID structure. There are lots of 458*da6c28aaSamw * simplifying assumptions in here. The memory for the SID is allocated 459*da6c28aaSamw * as if it was the largest possible SID; the caller is responsible for 460*da6c28aaSamw * freeing the memory when it is no longer required. We assume that the 461*da6c28aaSamw * string starts with "S-1-" and that the authority is held in the last 462*da6c28aaSamw * byte, which should be okay for most situations. It also assumes the 463*da6c28aaSamw * sub-authorities are in decimal format. 464*da6c28aaSamw * 465*da6c28aaSamw * On success, a pointer to a SID is returned. Otherwise a null pointer 466*da6c28aaSamw * is returned. 467*da6c28aaSamw * 468*da6c28aaSamw * XXX this function may have endian issues 469*da6c28aaSamw */ 470*da6c28aaSamw nt_sid_t * 471*da6c28aaSamw nt_sid_strtosid(char *sidstr) 472*da6c28aaSamw { 473*da6c28aaSamw nt_sid_t *sid; 474*da6c28aaSamw char *p; 475*da6c28aaSamw int size; 476*da6c28aaSamw BYTE i; 477*da6c28aaSamw #ifdef _KERNEL 478*da6c28aaSamw long sua; 479*da6c28aaSamw #endif /* _KERNEL */ 480*da6c28aaSamw 481*da6c28aaSamw if (sidstr == 0) { 482*da6c28aaSamw return (0); 483*da6c28aaSamw } 484*da6c28aaSamw 485*da6c28aaSamw if (strncmp(sidstr, "S-1-", 4) != 0) { 486*da6c28aaSamw return (0); 487*da6c28aaSamw } 488*da6c28aaSamw 489*da6c28aaSamw size = sizeof (nt_sid_t) + (NT_SID_SUBAUTH_MAX * sizeof (DWORD)); 490*da6c28aaSamw 491*da6c28aaSamw if ((sid = MEM_MALLOC("libnt", size)) == 0) { 492*da6c28aaSamw return (0); 493*da6c28aaSamw } 494*da6c28aaSamw 495*da6c28aaSamw bzero(sid, size); 496*da6c28aaSamw sid->Revision = NT_SID_REVISION; 497*da6c28aaSamw #ifndef _KERNEL 498*da6c28aaSamw sid->Authority[5] = atoi(&sidstr[4]); 499*da6c28aaSamw #else /* _KERNEL */ 500*da6c28aaSamw sua = 0; 501*da6c28aaSamw /* XXX Why are we treating sua as a long/unsigned long? */ 502*da6c28aaSamw (void) ddi_strtoul(&sidstr[4], 0, 10, (unsigned long *)&sua); 503*da6c28aaSamw sid->Authority[5] = (BYTE)sua; 504*da6c28aaSamw #endif /* _KERNEL */ 505*da6c28aaSamw 506*da6c28aaSamw for (i = 0, p = &sidstr[5]; i < NT_SID_SUBAUTH_MAX && *p; ++i) { 507*da6c28aaSamw while (*p && *p == '-') 508*da6c28aaSamw ++p; 509*da6c28aaSamw 510*da6c28aaSamw if (*p < '0' || *p > '9') { 511*da6c28aaSamw MEM_FREE("libnt", sid); 512*da6c28aaSamw return (0); 513*da6c28aaSamw } 514*da6c28aaSamw 515*da6c28aaSamw #ifndef _KERNEL 516*da6c28aaSamw sid->SubAuthority[i] = strtoul(p, 0, 10); 517*da6c28aaSamw #else /* _KERNEL */ 518*da6c28aaSamw sua = 0; 519*da6c28aaSamw (void) ddi_strtoul(p, 0, 10, (unsigned long *)&sua); 520*da6c28aaSamw sid->SubAuthority[i] = (DWORD)sua; 521*da6c28aaSamw #endif /* _KERNEL */ 522*da6c28aaSamw 523*da6c28aaSamw while (*p && *p != '-') 524*da6c28aaSamw ++p; 525*da6c28aaSamw } 526*da6c28aaSamw 527*da6c28aaSamw sid->SubAuthCount = i; 528*da6c28aaSamw return (sid); 529*da6c28aaSamw } 530*da6c28aaSamw 531*da6c28aaSamw 532*da6c28aaSamw /* 533*da6c28aaSamw * nt_sid_name_use 534*da6c28aaSamw * 535*da6c28aaSamw * Returns the text name for a SID_NAME_USE value. The SID_NAME_USE 536*da6c28aaSamw * provides the context for a SID, i.e. the type of resource to which 537*da6c28aaSamw * it refers. 538*da6c28aaSamw */ 539*da6c28aaSamw char * 540*da6c28aaSamw nt_sid_name_use(unsigned int snu_id) 541*da6c28aaSamw { 542*da6c28aaSamw static char *snu_name[] = { 543*da6c28aaSamw "SidTypeSidPrefix", 544*da6c28aaSamw "SidTypeUser", 545*da6c28aaSamw "SidTypeGroup", 546*da6c28aaSamw "SidTypeDomain", 547*da6c28aaSamw "SidTypeAlias", 548*da6c28aaSamw "SidTypeWellKnownGroup", 549*da6c28aaSamw "SidTypeDeletedAccount", 550*da6c28aaSamw "SidTypeInvalid", 551*da6c28aaSamw "SidTypeUnknown" 552*da6c28aaSamw }; 553*da6c28aaSamw 554*da6c28aaSamw if (snu_id < ((sizeof (snu_name)/sizeof (snu_name[0])))) 555*da6c28aaSamw return (snu_name[snu_id]); 556*da6c28aaSamw else { 557*da6c28aaSamw return (snu_name[SidTypeUnknown]); 558*da6c28aaSamw } 559*da6c28aaSamw } 560*da6c28aaSamw 561*da6c28aaSamw 562*da6c28aaSamw /* 563*da6c28aaSamw * nt_sid_copy 564*da6c28aaSamw * 565*da6c28aaSamw * Copy information of srcsid to dessid. The buffer should be allocated 566*da6c28aaSamw * for dessid before passing to this function. The size of buffer for 567*da6c28aaSamw * dessid should be specified in the buflen. 568*da6c28aaSamw * 569*da6c28aaSamw * Returns total bytes of information copied. If there is an error, 0 570*da6c28aaSamw * will be returned. 571*da6c28aaSamw */ 572*da6c28aaSamw int 573*da6c28aaSamw nt_sid_copy(nt_sid_t *dessid, nt_sid_t *srcsid, unsigned buflen) 574*da6c28aaSamw { 575*da6c28aaSamw unsigned n_bytes; 576*da6c28aaSamw 577*da6c28aaSamw if (!dessid || !srcsid) 578*da6c28aaSamw return (0); 579*da6c28aaSamw 580*da6c28aaSamw n_bytes = nt_sid_length(srcsid); 581*da6c28aaSamw if (n_bytes > buflen) 582*da6c28aaSamw return (0); 583*da6c28aaSamw 584*da6c28aaSamw bcopy((char *)srcsid, (char *)dessid, n_bytes); 585*da6c28aaSamw 586*da6c28aaSamw return (n_bytes); 587*da6c28aaSamw } 588