Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/libcli/security/dom_sid.c

    r583 r745  
    2929*****************************************************************/
    3030
    31 static int dom_sid_compare_auth(const struct dom_sid *sid1,
    32                                 const struct dom_sid *sid2)
     31int dom_sid_compare_auth(const struct dom_sid *sid1,
     32                         const struct dom_sid *sid2)
    3333{
    3434        int i;
     
    8686}
    8787
    88 /* Yes, I did think about multibyte issues here, and for all I can see there's
    89  * none of those for parsing a SID. */
    90 #undef strncasecmp
     88/*****************************************************************
     89 Add a rid to the end of a sid
     90*****************************************************************/
     91
     92bool sid_append_rid(struct dom_sid *sid, uint32_t rid)
     93{
     94        if (sid->num_auths < ARRAY_SIZE(sid->sub_auths)) {
     95                sid->sub_auths[sid->num_auths++] = rid;
     96                return true;
     97        }
     98        return false;
     99}
     100
     101/*
     102  See if 2 SIDs are in the same domain
     103  this just compares the leading sub-auths
     104*/
     105int dom_sid_compare_domain(const struct dom_sid *sid1,
     106                           const struct dom_sid *sid2)
     107{
     108        int n, i;
     109
     110        n = MIN(sid1->num_auths, sid2->num_auths);
     111
     112        for (i = n-1; i >= 0; --i)
     113                if (sid1->sub_auths[i] != sid2->sub_auths[i])
     114                        return sid1->sub_auths[i] - sid2->sub_auths[i];
     115
     116        return dom_sid_compare_auth(sid1, sid2);
     117}
     118
     119/*****************************************************************
     120 Convert a string to a SID. Returns True on success, False on fail.
     121 Return the first character not parsed in endp.
     122*****************************************************************/
     123
     124bool dom_sid_parse_endp(const char *sidstr,struct dom_sid *sidout,
     125                        const char **endp)
     126{
     127        const char *p;
     128        char *q;
     129        /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
     130        uint32_t conv;
     131
     132        ZERO_STRUCTP(sidout);
     133
     134        if ((sidstr[0] != 'S' && sidstr[0] != 's') || sidstr[1] != '-') {
     135                goto format_error;
     136        }
     137
     138        /* Get the revision number. */
     139        p = sidstr + 2;
     140
     141        if (!isdigit(*p)) {
     142                goto format_error;
     143        }
     144
     145        conv = (uint32_t) strtoul(p, &q, 10);
     146        if (!q || (*q != '-')) {
     147                goto format_error;
     148        }
     149        sidout->sid_rev_num = (uint8_t) conv;
     150        q++;
     151
     152        if (!isdigit(*q)) {
     153                goto format_error;
     154        }
     155
     156        /* get identauth */
     157        conv = (uint32_t) strtoul(q, &q, 10);
     158        if (!q) {
     159                goto format_error;
     160        }
     161
     162        /* identauth in decimal should be <  2^32 */
     163        /* NOTE - the conv value is in big-endian format. */
     164        sidout->id_auth[0] = 0;
     165        sidout->id_auth[1] = 0;
     166        sidout->id_auth[2] = (conv & 0xff000000) >> 24;
     167        sidout->id_auth[3] = (conv & 0x00ff0000) >> 16;
     168        sidout->id_auth[4] = (conv & 0x0000ff00) >> 8;
     169        sidout->id_auth[5] = (conv & 0x000000ff);
     170
     171        sidout->num_auths = 0;
     172        if (*q != '-') {
     173                /* Just id_auth, no subauths */
     174                return true;
     175        }
     176
     177        q++;
     178
     179        while (true) {
     180                char *end;
     181
     182                if (!isdigit(*q)) {
     183                        goto format_error;
     184                }
     185
     186                conv = strtoul(q, &end, 10);
     187                if (end == q) {
     188                        goto format_error;
     189                }
     190
     191                if (!sid_append_rid(sidout, conv)) {
     192                        DEBUG(3, ("Too many sid auths in %s\n", sidstr));
     193                        return false;
     194                }
     195
     196                q = end;
     197                if (*q != '-') {
     198                        break;
     199                }
     200                q += 1;
     201        }
     202        if (endp != NULL) {
     203                *endp = q;
     204        }
     205        return true;
     206
     207format_error:
     208        DEBUG(3, ("string_to_sid: SID %s is not in a valid format\n", sidstr));
     209        return false;
     210}
     211
     212bool string_to_sid(struct dom_sid *sidout, const char *sidstr)
     213{
     214        return dom_sid_parse(sidstr, sidout);
     215}
    91216
    92217bool dom_sid_parse(const char *sidstr, struct dom_sid *ret)
    93218{
    94         uint_t rev, ia, num_sub_auths, i;
    95         char *p;
    96 
    97         if (strncasecmp(sidstr, "S-", 2)) {
    98                 return false;
    99         }
    100 
    101         sidstr += 2;
    102 
    103         rev = strtol(sidstr, &p, 10);
    104         if (*p != '-') {
    105                 return false;
    106         }
    107         sidstr = p+1;
    108 
    109         ia = strtol(sidstr, &p, 10);
    110         if (p == sidstr) {
    111                 return false;
    112         }
    113         sidstr = p;
    114 
    115         num_sub_auths = 0;
    116         for (i=0;sidstr[i];i++) {
    117                 if (sidstr[i] == '-') num_sub_auths++;
    118         }
    119 
    120         if (num_sub_auths > MAXSUBAUTHS) {
    121                 return false;
    122         }
    123 
    124         ret->sid_rev_num = rev;
    125         ret->id_auth[0] = 0;
    126         ret->id_auth[1] = 0;
    127         ret->id_auth[2] = ia >> 24;
    128         ret->id_auth[3] = ia >> 16;
    129         ret->id_auth[4] = ia >> 8;
    130         ret->id_auth[5] = ia;
    131         ret->num_auths = num_sub_auths;
    132 
    133         for (i=0;i<num_sub_auths;i++) {
    134                 if (sidstr[0] != '-') {
    135                         return false;
    136                 }
    137                 sidstr++;
    138                 ret->sub_auths[i] = strtoul(sidstr, &p, 10);
    139                 if (p == sidstr) {
    140                         return false;
    141                 }
    142                 sidstr = p;
    143         }
    144 
    145         return true;
     219        return dom_sid_parse_endp(sidstr, ret, NULL);
    146220}
    147221
     
    222296        struct dom_sid *sid;
    223297
    224         sid = talloc(mem_ctx, struct dom_sid);
     298        sid = dom_sid_dup(mem_ctx, domain_sid);
    225299        if (!sid) return NULL;
    226300
    227         *sid = *domain_sid;
    228 
    229         sid->sub_auths[sid->num_auths] = rid;
    230         sid->num_auths++;
     301        if (!sid_append_rid(sid, rid)) {
     302                talloc_free(sid);
     303                return NULL;
     304        }
    231305
    232306        return sid;
     
    284358
    285359/*
    286   convert a dom_sid to a string
    287 */
    288 char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
    289 {
    290         int i, ofs, maxlen;
     360  Convert a dom_sid to a string, printing into a buffer. Return the
     361  string length. If it overflows, return the string length that would
     362  result (buflen needs to be +1 for the terminating 0).
     363*/
     364int dom_sid_string_buf(const struct dom_sid *sid, char *buf, int buflen)
     365{
     366        int i, ofs;
    291367        uint32_t ia;
    292         char *ret;
    293368
    294369        if (!sid) {
    295                 return talloc_strdup(mem_ctx, "(NULL SID)");
    296         }
    297 
    298         maxlen = sid->num_auths * 11 + 25;
    299         ret = talloc_array(mem_ctx, char, maxlen);
    300         if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)");
     370                strlcpy(buf, "(NULL SID)", buflen);
     371                return 10;      /* strlen("(NULL SID)") */
     372        }
    301373
    302374        ia = (sid->id_auth[5]) +
     
    305377                (sid->id_auth[2] << 24);
    306378
    307         ofs = snprintf(ret, maxlen, "S-%u-%lu",
     379        ofs = snprintf(buf, buflen, "S-%u-%lu",
    308380                       (unsigned int)sid->sid_rev_num, (unsigned long)ia);
    309381
    310382        for (i = 0; i < sid->num_auths; i++) {
    311                 ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu",
     383                ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%lu",
    312384                                (unsigned long)sid->sub_auths[i]);
    313385        }
    314 
    315         return ret;
    316 }
     386        return ofs;
     387}
     388
     389/*
     390  convert a dom_sid to a string
     391*/
     392char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
     393{
     394        char buf[DOM_SID_STR_BUFLEN];
     395        char *result;
     396        int len;
     397
     398        len = dom_sid_string_buf(sid, buf, sizeof(buf));
     399
     400        if (len+1 > sizeof(buf)) {
     401                return talloc_strdup(mem_ctx, "(SID ERR)");
     402        }
     403
     404        /*
     405         * Avoid calling strlen (via talloc_strdup), we already have
     406         * the length
     407         */
     408        result = (char *)talloc_memdup(mem_ctx, buf, len+1);
     409
     410        /*
     411         * beautify the talloc_report output
     412         */
     413        talloc_set_name_const(result, result);
     414        return result;
     415}
Note: See TracChangeset for help on using the changeset viewer.