"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/lib/isc/win32/ntgroups.c" (7 Sep 2020, 5124 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.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 "ntgroups.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 
   13 /*
   14  * The NT Groups have two groups that are not well documented and are
   15  * not normally seen: None and Everyone.  A user account belongs to
   16  * any number of groups, but if it is not a member of any group then
   17  * it is a member of the None Group. The None group is not listed
   18  * anywhere. You cannot remove an account from the none group except
   19  * by making it a member of some other group, The second group is the
   20  * Everyone group.  All accounts, no matter how many groups that they
   21  * belong to, also belong to the Everyone group. You cannot remove an
   22  * account from the Everyone group.
   23  */
   24 
   25 #ifndef UNICODE
   26 #define UNICODE
   27 #endif /* UNICODE */
   28 
   29 /*
   30  * Silence warnings.
   31  */
   32 #define _CRT_SECURE_NO_DEPRECATE 1
   33 
   34 #include <windows.h>
   35 #include <assert.h>
   36 #include <lm.h>
   37 
   38 #include <isc/ntgroups.h>
   39 #include <isc/result.h>
   40 
   41 #define MAX_NAME_LENGTH 256
   42 
   43 #define CHECK(op) \
   44     do { result = (op); if (result != ISC_R_SUCCESS) { goto cleanup; } } while (0)
   45 
   46 isc_result_t
   47 isc_ntsecurity_getaccountgroups(char *username, char **GroupList,
   48                 unsigned int maxgroups,
   49                 unsigned int *totalGroups)
   50 {
   51     LPGROUP_USERS_INFO_0 pTmpBuf;
   52     LPLOCALGROUP_USERS_INFO_0 pTmpLBuf;
   53     DWORD i;
   54     LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
   55     LPGROUP_USERS_INFO_0 pgrpBuf = NULL;
   56     DWORD dwLevel = 0;
   57     DWORD dwFlags = LG_INCLUDE_INDIRECT;
   58     DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
   59     DWORD dwEntriesRead = 0;
   60     DWORD dwTotalEntries = 0;
   61     NET_API_STATUS nStatus;
   62     size_t retlen;
   63     wchar_t user[MAX_NAME_LENGTH];
   64     isc_result_t result;
   65 
   66     *totalGroups = 0;
   67 
   68     retlen = mbstowcs(user, username, MAX_NAME_LENGTH);
   69     if (retlen == (size_t) (-1)) {
   70         return (ISC_R_FAILURE);
   71     }
   72 
   73     /*
   74      * Call the NetUserGetLocalGroups function
   75      * specifying information level 0.
   76      *
   77      * The LG_INCLUDE_INDIRECT flag specifies that the
   78      * function should also return the names of the local
   79      * groups in which the user is indirectly a member.
   80      */
   81     nStatus = NetUserGetLocalGroups(NULL, user, dwLevel, dwFlags,
   82                     (LPBYTE *) &pBuf, dwPrefMaxLen,
   83                     &dwEntriesRead, &dwTotalEntries);
   84     /*
   85      * See if the call succeeds,
   86      */
   87     if (nStatus != NERR_Success) {
   88         if (nStatus == ERROR_ACCESS_DENIED) {
   89             return (ISC_R_NOPERM);
   90         }
   91         if (nStatus == ERROR_MORE_DATA) {
   92             return (ISC_R_NOSPACE);
   93         }
   94         if (nStatus == NERR_UserNotFound) {
   95             dwEntriesRead = 0;
   96         }
   97     }
   98 
   99     if (pBuf != NULL) {
  100         pTmpLBuf = pBuf;
  101         /*
  102          * Loop through the entries
  103          */
  104          for (i = 0;
  105              (i < dwEntriesRead && *totalGroups < maxgroups); i++) {
  106             assert(pTmpLBuf != NULL);
  107             if (pTmpLBuf == NULL) {
  108                 break;
  109             }
  110             retlen = wcslen(pTmpLBuf->lgrui0_name);
  111             GroupList[*totalGroups] = (char *) malloc(retlen +1);
  112             if (GroupList[*totalGroups] == NULL) {
  113                 CHECK(ISC_R_NOMEMORY);
  114             }
  115 
  116             retlen = wcstombs(GroupList[*totalGroups],
  117                       pTmpLBuf->lgrui0_name, retlen);
  118             if (retlen == (size_t) (-1)) {
  119                 free(GroupList[*totalGroups]);
  120                 CHECK(ISC_R_FAILURE);
  121             }
  122             GroupList[*totalGroups][retlen] = '\0';
  123             if (strcmp(GroupList[*totalGroups], "None") == 0) {
  124                 free(GroupList[*totalGroups]);
  125             } else {
  126                 (*totalGroups)++;
  127             }
  128             pTmpLBuf++;
  129         }
  130     }
  131     /* Free the allocated memory. */
  132     /* cppcheck-suppress duplicateCondition */
  133     if (pBuf != NULL)
  134         NetApiBufferFree(pBuf);
  135 
  136 
  137     /*
  138      * Call the NetUserGetGroups function, specifying level 0.
  139      */
  140     nStatus = NetUserGetGroups(NULL, user, dwLevel,
  141                   (LPBYTE*)&pgrpBuf, dwPrefMaxLen,
  142                    &dwEntriesRead, &dwTotalEntries);
  143     /*
  144      * See if the call succeeds,
  145      */
  146     if (nStatus != NERR_Success) {
  147         if (nStatus == ERROR_ACCESS_DENIED) {
  148             return (ISC_R_NOPERM);
  149         }
  150         if (nStatus == ERROR_MORE_DATA) {
  151             return (ISC_R_NOSPACE);
  152         }
  153         if (nStatus == NERR_UserNotFound) {
  154             dwEntriesRead = 0;
  155         }
  156     }
  157 
  158     if (pgrpBuf != NULL) {
  159         pTmpBuf = pgrpBuf;
  160         /*
  161          * Loop through the entries
  162          */
  163          for (i = 0;
  164              (i < dwEntriesRead && *totalGroups < maxgroups); i++) {
  165             assert(pTmpBuf != NULL);
  166 
  167             if (pTmpBuf == NULL) {
  168                 break;
  169             }
  170             retlen = wcslen(pTmpBuf->grui0_name);
  171             GroupList[*totalGroups] = (char *) malloc(retlen +1);
  172             if (GroupList[*totalGroups] == NULL) {
  173                 CHECK(ISC_R_NOMEMORY);
  174             }
  175 
  176             retlen = wcstombs(GroupList[*totalGroups],
  177                  pTmpBuf->grui0_name, retlen);
  178             if (retlen == (size_t) (-1)) {
  179                 free(GroupList[*totalGroups]);
  180                 CHECK(ISC_R_FAILURE);
  181             }
  182             GroupList[*totalGroups][retlen] = '\0';
  183             if (strcmp(GroupList[*totalGroups], "None") == 0) {
  184                 free(GroupList[*totalGroups]);
  185             } else {
  186                 (*totalGroups)++;
  187             }
  188             pTmpBuf++;
  189         }
  190     }
  191     /*
  192      * Free the allocated memory.
  193      */
  194     /* cppcheck-suppress duplicateCondition */
  195     if (pgrpBuf != NULL) {
  196         NetApiBufferFree(pgrpBuf);
  197     }
  198 
  199     return (ISC_R_SUCCESS);
  200 
  201  cleanup:
  202     while (--(*totalGroups) > 0) {
  203         free(GroupList[*totalGroups]);
  204     }
  205     return (result);
  206 }