"Fossies" - the Fresh Open Source Software Archive

Member "ntfsprogs-1.12.1/libntfs/security.c" (28 Sep 2005, 7350 Bytes) of package /linux/misc/old/ntfsprogs-1.12.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "security.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * security.c - Code for handling security/ACLs in NTFS.  Part of the
    3  *      Linux-NTFS project.
    4  *
    5  * Copyright (c) 2004 Anton Altaparmakov
    6  *
    7  * This program/include file is free software; you can redistribute it and/or
    8  * modify it under the terms of the GNU General Public License as published
    9  * by the Free Software Foundation; either version 2 of the License, or
   10  * (at your option) any later version.
   11  *
   12  * This program/include file is distributed in the hope that it will be
   13  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
   14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15  * GNU General Public License for more details.
   16  *
   17  * You should have received a copy of the GNU General Public License
   18  * along with this program (in the main directory of the Linux-NTFS
   19  * distribution in the file COPYING); if not, write to the Free Software
   20  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   21  */
   22 
   23 #include "config.h"
   24 
   25 #ifdef HAVE_STDIO_H
   26 #include <stdio.h>
   27 #endif
   28 #ifdef HAVE_STDLIB_H
   29 #include <stdlib.h>
   30 #endif
   31 #ifdef HAVE_STRING_H
   32 #include <string.h>
   33 #endif
   34 #ifdef HAVE_ERRNO_H
   35 #include <errno.h>
   36 #endif
   37 
   38 #include "types.h"
   39 #include "layout.h"
   40 #include "security.h"
   41 
   42 /*
   43  * The zero GUID.
   44  */
   45 static const GUID __zero_guid = { const_cpu_to_le32(0), const_cpu_to_le16(0),
   46         const_cpu_to_le16(0), { 0, 0, 0, 0, 0, 0, 0, 0 } };
   47 const GUID *const zero_guid = &__zero_guid;
   48 
   49 /**
   50  * ntfs_guid_is_zero - check if a GUID is zero
   51  * @guid:   [IN] guid to check
   52  *
   53  * Return TRUE if @guid is a valid pointer to a GUID and it is the zero GUID
   54  * and FALSE otherwise.
   55  */
   56 BOOL ntfs_guid_is_zero(const GUID *guid)
   57 {
   58     return (memcmp(guid, zero_guid, sizeof(*zero_guid)));
   59 }
   60 
   61 /**
   62  * ntfs_guid_to_mbs - convert a GUID to a multi byte string
   63  * @guid:   [IN]  guid to convert
   64  * @guid_str:   [OUT] string in which to return the GUID (optional)
   65  *
   66  * Convert the GUID pointed to by @guid to a multi byte string of the form
   67  * "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX".  Therefore, @guid_str (if not NULL)
   68  * needs to be able to store at least 37 bytes.
   69  *
   70  * If @guid_str is not NULL it will contain the converted GUID on return.  If
   71  * it is NULL a string will be allocated and this will be returned.  The caller
   72  * is responsible for free()ing the string in that case.
   73  *
   74  * On success return the converted string and on failure return NULL with errno
   75  * set to the error code.
   76  */
   77 char *ntfs_guid_to_mbs(const GUID *guid, char *guid_str)
   78 {
   79     char *_guid_str;
   80     int res;
   81 
   82     if (!guid) {
   83         errno = EINVAL;
   84         return NULL;
   85     }
   86     _guid_str = guid_str;
   87     if (!_guid_str) {
   88         _guid_str = malloc(37);
   89         if (!_guid_str)
   90             return _guid_str;
   91     }
   92     res = snprintf(_guid_str, 37,
   93             "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
   94             (unsigned int)le32_to_cpu(guid->data1),
   95             le16_to_cpu(guid->data2), le16_to_cpu(guid->data3),
   96             guid->data4[0], guid->data4[1],
   97             guid->data4[2], guid->data4[3], guid->data4[4],
   98             guid->data4[5], guid->data4[6], guid->data4[7]);
   99     if (res == 36)
  100            return _guid_str;
  101     if (!guid_str)
  102         free(_guid_str);
  103     errno = EINVAL;
  104     return NULL;
  105 }
  106 
  107 /**
  108  * ntfs_sid_to_mbs_size - determine maximum size for the string of a SID
  109  * @sid:    [IN]  SID for which to determine the maximum string size
  110  *
  111  * Determine the maximum multi byte string size in bytes which is needed to
  112  * store the standard textual representation of the SID pointed to by @sid.
  113  * See ntfs_sid_to_mbs(), below.
  114  *
  115  * On success return the maximum number of bytes needed to store the multi byte
  116  * string and on failure return -1 with errno set to the error code.
  117  */
  118 int ntfs_sid_to_mbs_size(const SID *sid)
  119 {
  120     int size, i;
  121 
  122     if (!ntfs_sid_is_valid(sid)) {
  123         errno = EINVAL;
  124         return -1;
  125     }
  126     /* Start with "S-". */
  127     size = 2;
  128     /*
  129      * Add the SID_REVISION.  Hopefully the compiler will optimize this
  130      * away as SID_REVISION is a constant.
  131      */
  132     for (i = SID_REVISION; i > 0; i /= 10)
  133         size++;
  134     /* Add the "-". */
  135     size++;
  136     /*
  137      * Add the identifier authority.  If it needs to be in decimal, the
  138      * maximum is 2^32-1 = 4294967295 = 10 characters.  If it needs to be
  139      * in hexadecimal, then maximum is 0x665544332211 = 14 characters.
  140      */
  141     if (!sid->identifier_authority.high_part)
  142         size += 10;
  143     else
  144         size += 14;
  145     /*
  146      * Finally, add the sub authorities.  For each we have a "-" followed
  147      * by a decimal which can be up to 2^32-1 = 4294967295 = 10 characters.
  148      */
  149     size += (1 + 10) * sid->sub_authority_count;
  150     /* We need the zero byte at the end, too. */
  151     size++;
  152     return size * sizeof(char);
  153 }
  154 
  155 /**
  156  * ntfs_sid_to_mbs - convert a SID to a multi byte string
  157  * @sid:        [IN]  SID to convert
  158  * @sid_str:        [OUT] string in which to return the SID (optional)
  159  * @sid_str_size:   [IN]  size in bytes of @sid_str
  160  *
  161  * Convert the SID pointed to by @sid to its standard textual representation.
  162  * @sid_str (if not NULL) needs to be able to store at least
  163  * ntfs_sid_to_mbs_size() bytes.  @sid_str_size is the size in bytes of
  164  * @sid_str if @sid_str is not NULL.
  165  *
  166  * The standard textual representation of the SID is of the form:
  167  *  S-R-I-S-S...
  168  * Where:
  169  *    - The first "S" is the literal character 'S' identifying the following
  170  *  digits as a SID.
  171  *    - R is the revision level of the SID expressed as a sequence of digits
  172  *  in decimal.
  173  *    - I is the 48-bit identifier_authority, expressed as digits in decimal,
  174  *  if I < 2^32, or hexadecimal prefixed by "0x", if I >= 2^32.
  175  *    - S... is one or more sub_authority values, expressed as digits in
  176  *  decimal.
  177  *
  178  * If @sid_str is not NULL it will contain the converted SUID on return.  If it
  179  * is NULL a string will be allocated and this will be returned.  The caller is
  180  * responsible for free()ing the string in that case.
  181  *
  182  * On success return the converted string and on failure return NULL with errno
  183  * set to the error code.
  184  */
  185 char *ntfs_sid_to_mbs(const SID *sid, char *sid_str, size_t sid_str_size)
  186 {
  187     u64 u;
  188     char *s;
  189     int i, j, cnt;
  190 
  191     /*
  192      * No need to check @sid if !@sid_str since ntfs_sid_to_mbs_size() will
  193      * check @sid, too.  8 is the minimum SID string size.
  194      */
  195     if (sid_str && (sid_str_size < 8 || !ntfs_sid_is_valid(sid))) {
  196         errno = EINVAL;
  197         return NULL;
  198     }
  199     /* Allocate string if not provided. */
  200     if (!sid_str) {
  201         cnt = ntfs_sid_to_mbs_size(sid);
  202         if (cnt < 0)
  203             return NULL;
  204         s = malloc(cnt);
  205         if (!s)
  206             return s;
  207         sid_str = s;
  208         /* So we know we allocated it. */
  209         sid_str_size = 0;
  210     } else {
  211         s = sid_str;
  212         cnt = sid_str_size;
  213     }
  214     /* Start with "S-R-". */
  215     i = snprintf(s, cnt, "S-%hhu-", (unsigned char)sid->revision);
  216     if (i < 0 || i >= cnt)
  217         goto err_out;
  218     s += i;
  219     cnt -= i;
  220     /* Add the identifier authority. */
  221     for (u = i = 0, j = 40; i < 6; i++, j -= 8)
  222         u += (u64)sid->identifier_authority.value[i] << j;
  223     if (!sid->identifier_authority.high_part)
  224         i = snprintf(s, cnt, "%lu", (unsigned long)u);
  225     else
  226         i = snprintf(s, cnt, "0x%llx", (unsigned long long)u);
  227     if (i < 0 || i >= cnt)
  228         goto err_out;
  229     s += i;
  230     cnt -= i;
  231     /* Finally, add the sub authorities. */
  232     for (j = 0; j < sid->sub_authority_count; j++) {
  233         i = snprintf(s, cnt, "-%u", (unsigned int)
  234                 le32_to_cpu(sid->sub_authority[j]));
  235         if (i < 0 || i >= cnt)
  236             goto err_out;
  237         s += i;
  238         cnt -= i;
  239     }
  240     return sid_str;
  241 err_out:
  242     if (i >= cnt)
  243         i = EMSGSIZE;
  244     else
  245         i = errno;
  246     if (!sid_str_size)
  247         free(sid_str);
  248     errno = i;
  249     return NULL;
  250 }