LCOV - code coverage report
Current view: top level - tools - sss_groupshow.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 0 355 0.0 %
Date: 2015-10-19 Functions: 0 11 0.0 %

          Line data    Source code
       1             : /*
       2             :    SSSD
       3             : 
       4             :    sss_groupshow
       5             : 
       6             :    Copyright (C) Jakub Hrozek <jhrozek@redhat.com>        2010
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <talloc.h>
      25             : #include <popt.h>
      26             : 
      27             : #include "db/sysdb.h"
      28             : #include "util/util.h"
      29             : #include "tools/tools_util.h"
      30             : #include "tools/sss_sync_ops.h"
      31             : 
      32             : #define PADDING_SPACES   4
      33             : #define GROUP_SHOW_ATTRS { SYSDB_MEMBEROF, SYSDB_GIDNUM, \
      34             :                            SYSDB_MEMBER, SYSDB_GHOST, SYSDB_NAME, \
      35             :                            NULL }
      36             : #define GROUP_SHOW_MPG_ATTRS { SYSDB_MEMBEROF, SYSDB_UIDNUM, \
      37             :                                 SYSDB_NAME, NULL }
      38             : 
      39             : struct group_info {
      40             :     const char *name;
      41             :     gid_t gid;
      42             :     bool  mpg;
      43             : 
      44             :     const char **user_members;
      45             :     const char **memberofs;
      46             : 
      47             :     struct group_info **group_members;
      48             : };
      49             : 
      50             : /*==================Helper routines to process results================= */
      51           0 : const char *rdn_as_string(TALLOC_CTX *mem_ctx,
      52             :                           struct ldb_dn *dn)
      53             : {
      54             :     const struct ldb_val *val;
      55             : 
      56           0 :     val = ldb_dn_get_rdn_val(dn);
      57           0 :     if (val == NULL) {
      58           0 :         return NULL;
      59             :     }
      60             : 
      61           0 :     return ldb_dn_escape_value(mem_ctx, *val);;
      62             : }
      63             : 
      64           0 : static int parse_memberofs(struct ldb_context *ldb,
      65             :                            struct ldb_message_element *el,
      66             :                            struct group_info *gi)
      67             : {
      68             :     int i;
      69           0 :     struct ldb_dn *dn = NULL;
      70             : 
      71           0 :     gi->memberofs = talloc_array(gi, const char *, el->num_values+1);
      72           0 :     if (gi->memberofs == NULL) {
      73           0 :         return ENOMEM;
      74             :     }
      75             : 
      76           0 :     for (i = 0; i< el->num_values; ++i) {
      77           0 :         dn = ldb_dn_from_ldb_val(gi, ldb, &(el->values[i]));
      78           0 :         gi->memberofs[i] = talloc_strdup(gi, rdn_as_string(gi, dn));
      79           0 :         talloc_zfree(dn);
      80           0 :         if (gi->memberofs[i] == NULL) {
      81           0 :             return ENOMEM;
      82             :         }
      83           0 :         DEBUG(SSSDBG_TRACE_FUNC, "memberof value: %s\n", gi->memberofs[i]);
      84             :     }
      85           0 :     gi->memberofs[el->num_values] = NULL;
      86             : 
      87           0 :     return EOK;
      88             : }
      89             : 
      90           0 : static int parse_members(TALLOC_CTX *mem_ctx,
      91             :                          struct ldb_context *ldb,
      92             :                          struct sss_domain_info *domain,
      93             :                          struct ldb_message_element *el,
      94             :                          const  char *parent_name,
      95             :                          const  char ***user_members,
      96             :                          const  char ***group_members,
      97             :                          int    *num_group_members)
      98             : {
      99           0 :     struct ldb_dn *user_basedn = NULL, *group_basedn = NULL;
     100           0 :     struct ldb_dn *parent_dn = NULL;
     101           0 :     struct ldb_dn *dn = NULL;
     102           0 :     const char **um = NULL, **gm = NULL;
     103           0 :     unsigned int um_index = 0, gm_index = 0;
     104           0 :     TALLOC_CTX *tmp_ctx = NULL;
     105             :     int ret;
     106             :     int i;
     107             : 
     108           0 :     tmp_ctx = talloc_new(mem_ctx);
     109           0 :     if (!tmp_ctx) {
     110           0 :         ret = ENOMEM;
     111           0 :         goto fail;
     112             :     }
     113             : 
     114           0 :     user_basedn = sysdb_user_base_dn(tmp_ctx, domain);
     115           0 :     group_basedn = sysdb_group_base_dn(tmp_ctx, domain);
     116           0 :     if (!user_basedn || !group_basedn) {
     117           0 :         ret = ENOMEM;
     118           0 :         goto fail;
     119             :     }
     120             : 
     121           0 :     um = talloc_array(mem_ctx, const char *, el->num_values+1);
     122           0 :     gm = talloc_array(mem_ctx, const char *, el->num_values+1);
     123           0 :     if (!um || !gm) {
     124           0 :         ret = ENOMEM;
     125           0 :         goto fail;
     126             :     }
     127             : 
     128           0 :     for (i = 0; i< el->num_values; ++i) {
     129           0 :         dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &(el->values[i]));
     130             : 
     131             :         /* user member or group member? */
     132           0 :         parent_dn = ldb_dn_get_parent(tmp_ctx, dn);
     133           0 :         if (ldb_dn_compare_base(parent_dn, user_basedn) == 0) {
     134           0 :             um[um_index] = rdn_as_string(mem_ctx, dn);
     135           0 :             if (um[um_index] == NULL) {
     136           0 :                 ret = ENOMEM;
     137           0 :                 goto fail;
     138             :             }
     139           0 :             DEBUG(SSSDBG_TRACE_FUNC, "User member %s\n", um[um_index]);
     140           0 :             um_index++;
     141           0 :         } else if (ldb_dn_compare_base(parent_dn, group_basedn) == 0) {
     142           0 :             gm[gm_index] = rdn_as_string(mem_ctx, dn);
     143           0 :             if (gm[gm_index] == NULL) {
     144           0 :                 ret = ENOMEM;
     145           0 :                 goto fail;
     146             :             }
     147           0 :             if (parent_name && strcmp(gm[gm_index], parent_name) == 0) {
     148           0 :                 DEBUG(SSSDBG_TRACE_FUNC,
     149             :                       "Skipping circular nesting for group %s\n",
     150             :                           gm[gm_index]);
     151           0 :                 continue;
     152             :             }
     153           0 :             DEBUG(SSSDBG_TRACE_FUNC, "Group member %s\n", gm[gm_index]);
     154           0 :             gm_index++;
     155             :         } else {
     156           0 :             DEBUG(SSSDBG_OP_FAILURE, "Group member not a user nor group: %s\n",
     157             :                         ldb_dn_get_linearized(dn));
     158           0 :             ret = EIO;
     159           0 :             goto fail;
     160             :         }
     161             : 
     162           0 :         talloc_zfree(dn);
     163           0 :         talloc_zfree(parent_dn);
     164             :     }
     165           0 :     um[um_index] = NULL;
     166           0 :     gm[gm_index] = NULL;
     167             : 
     168           0 :     if (um_index > 0) {
     169           0 :         um = talloc_realloc(mem_ctx, um, const char *, um_index+1);
     170           0 :         if (!um) {
     171           0 :             ret = ENOMEM;
     172           0 :             goto fail;
     173             :         }
     174             :     } else {
     175           0 :         talloc_zfree(um);
     176             :     }
     177             : 
     178           0 :     if (gm_index > 0) {
     179           0 :         gm = talloc_realloc(mem_ctx, gm, const char *, gm_index+1);
     180           0 :         if (!gm) {
     181           0 :             ret = ENOMEM;
     182           0 :             goto fail;
     183             :         }
     184             :     } else {
     185           0 :         talloc_zfree(gm);
     186             :     }
     187             : 
     188           0 :     *user_members = um;
     189           0 :     if (group_members) *group_members = gm;
     190           0 :     if (num_group_members) *num_group_members = gm_index;
     191           0 :     talloc_zfree(tmp_ctx);
     192           0 :     return EOK;
     193             : 
     194             : fail:
     195           0 :     talloc_zfree(um);
     196           0 :     talloc_zfree(gm);
     197           0 :     talloc_zfree(tmp_ctx);
     198           0 :     return ret;
     199             : }
     200             : 
     201           0 : static int process_group(TALLOC_CTX *mem_ctx,
     202             :                          struct ldb_context *ldb,
     203             :                          struct ldb_message *msg,
     204             :                          struct sss_domain_info *domain,
     205             :                          const  char *parent_name,
     206             :                          struct group_info **info,
     207             :                          const char ***group_members,
     208             :                          int    *num_group_members)
     209             : {
     210             :     struct ldb_message_element *el;
     211             :     int ret, i, j;
     212           0 :     int count = 0;
     213           0 :     struct group_info *gi = NULL;
     214             :     const char **user_members;
     215             : 
     216           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     217             :           "Found entry %s\n", ldb_dn_get_linearized(msg->dn));
     218             : 
     219           0 :     gi = talloc_zero(mem_ctx, struct group_info);
     220           0 :     if (!gi) {
     221           0 :         ret = ENOMEM;
     222           0 :         goto done;
     223             :     }
     224             : 
     225             :     /* mandatory data - name and gid */
     226           0 :     gi->name = talloc_strdup(gi,
     227             :                              ldb_msg_find_attr_as_string(msg,
     228             :                                                          SYSDB_NAME,
     229             :                                                          NULL));
     230           0 :     gi->gid = ldb_msg_find_attr_as_uint64(msg,
     231             :                                           SYSDB_GIDNUM, 0);
     232           0 :     if (gi->gid == 0 || gi->name == NULL) {
     233           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "No name or no GID?\n");
     234           0 :         ret = EIO;
     235           0 :         goto done;
     236             :     }
     237             : 
     238             :     /* list members */
     239           0 :     el = ldb_msg_find_element(msg, SYSDB_MEMBER);
     240           0 :     if (el) {
     241           0 :         ret = parse_members(gi, ldb, domain, el,
     242             :                             parent_name,
     243             :                             &gi->user_members,
     244             :                             group_members, num_group_members);
     245           0 :         if (ret != EOK) {
     246           0 :             goto done;
     247             :         }
     248           0 :         if (gi->user_members == NULL) {
     249           0 :             count = 0;
     250             :         } else {
     251           0 :             for (count = 0; gi->user_members[count]; count++) ;
     252             :         }
     253             :     }
     254           0 :     el = ldb_msg_find_element(msg, SYSDB_GHOST);
     255           0 :     if (el) {
     256           0 :         ret = parse_members(gi, ldb, domain, el,
     257             :                             parent_name,
     258             :                             &user_members,
     259             :                             NULL, NULL);
     260           0 :         if (ret != EOK) {
     261           0 :             goto done;
     262             :         }
     263             : 
     264           0 :         if (user_members != NULL) {
     265           0 :             i = count;
     266           0 :             for (count = 0; user_members[count]; count++) ;
     267           0 :             gi->user_members = talloc_realloc(gi, gi->user_members,
     268             :                                               const char *,
     269             :                                               i + count + 1);
     270           0 :             if (gi->user_members == NULL) {
     271           0 :                 ret = ENOMEM;
     272           0 :                 goto done;
     273             :             }
     274           0 :             for (j = 0; j < count; j++, i++) {
     275           0 :                 gi->user_members[i] = talloc_steal(gi->user_members,
     276             :                                                    user_members[j]);
     277             :             }
     278           0 :             gi->user_members[i] = NULL;
     279             : 
     280           0 :             talloc_zfree(user_members);
     281             :         }
     282             :     }
     283             : 
     284             :     /* list memberofs */
     285           0 :     el = ldb_msg_find_element(msg, SYSDB_MEMBEROF);
     286           0 :     if (el) {
     287           0 :         ret = parse_memberofs(ldb, el, gi);
     288           0 :         if (ret != EOK) {
     289           0 :             goto done;
     290             :         }
     291             :     }
     292             : 
     293           0 :     *info = gi;
     294           0 :     return EOK;
     295             : done:
     296           0 :     talloc_zfree(gi);
     297           0 :     return ret;
     298             : }
     299             : 
     300             : /*========Find info about a group and recursively about subgroups====== */
     301             : 
     302             : int group_show_recurse(TALLOC_CTX *mem_ctx,
     303             :                        struct sysdb_ctx *sysdb,
     304             :                        struct sss_domain_info *domain,
     305             :                        struct group_info *root,
     306             :                        struct group_info *parent,
     307             :                        const char **group_members,
     308             :                        const int  nmembers,
     309             :                        struct group_info ***up_members);
     310             : 
     311             : static int group_show_trim_memberof(TALLOC_CTX *mem_ctx,
     312             :                                     struct sss_domain_info *domain,
     313             :                                     const char *name,
     314             :                                     const char **memberofs,
     315             :                                     const char ***_direct);
     316             : 
     317           0 : int group_show(TALLOC_CTX *mem_ctx,
     318             :                struct sysdb_ctx *sysdb,
     319             :                struct sss_domain_info *domain,
     320             :                bool   recursive,
     321             :                const char *name,
     322             :                struct group_info **res)
     323             : {
     324             :     struct group_info *root;
     325             :     static const char *attrs[] = GROUP_SHOW_ATTRS;
     326           0 :     struct ldb_message *msg = NULL;
     327           0 :     const char **group_members = NULL;
     328           0 :     int nmembers = 0;
     329             :     int ret;
     330             :     int i;
     331             : 
     332             :     /* First, search for the root group */
     333           0 :     ret = sysdb_search_group_by_name(mem_ctx, domain, name, attrs, &msg);
     334           0 :     if (ret) {
     335           0 :         DEBUG(SSSDBG_OP_FAILURE,
     336             :               "Search failed: %s (%d)\n", strerror(ret), ret);
     337           0 :         goto done;
     338             :     }
     339             : 
     340           0 :     ret = process_group(mem_ctx, sysdb_ctx_get_ldb(sysdb),
     341             :                         msg, domain, NULL, &root,
     342             :                         &group_members, &nmembers);
     343           0 :     if (ret != EOK) {
     344           0 :         DEBUG(SSSDBG_OP_FAILURE, "Group processing failed: %s (%d)\n",
     345             :                    strerror(ret), ret);
     346           0 :         goto done;
     347             :     }
     348             : 
     349           0 :     if (!recursive) {
     350           0 :         if (group_members) {
     351           0 :             root->group_members = talloc_array(root,
     352             :                                                struct group_info *,
     353             :                                                nmembers+1);
     354           0 :             if (!root->group_members) {
     355           0 :                 ret = ENOMEM;
     356           0 :                 goto done;
     357             :             }
     358           0 :             for (i = 0; i < nmembers; i++) {
     359           0 :                 root->group_members[i] = talloc_zero(root, struct group_info);
     360           0 :                 if (!root->group_members[i]) {
     361           0 :                     ret = ENOMEM;
     362           0 :                     goto done;
     363             :                 }
     364           0 :                 root->group_members[i]->name = talloc_strdup(root,
     365           0 :                                                              group_members[i]);
     366           0 :                 if (!root->group_members[i]->name) {
     367           0 :                     ret = ENOMEM;
     368           0 :                     goto done;
     369             :                 }
     370             :             }
     371           0 :             root->group_members[nmembers] = NULL;
     372             :         }
     373             : 
     374           0 :         if (root->memberofs == NULL) {
     375           0 :             ret = EOK;
     376           0 :             goto done;
     377             :         }
     378             : 
     379             :         /* if not recursive, only show the direct parent */
     380           0 :         ret = group_show_trim_memberof(mem_ctx, domain, root->name,
     381           0 :                                        root->memberofs, &root->memberofs);
     382           0 :         goto done;
     383             :     }
     384             : 
     385           0 :     if (group_members == NULL) {
     386           0 :         ret = EOK;
     387           0 :         goto done;
     388             :     }
     389             : 
     390           0 :     ret = group_show_recurse(root, sysdb, domain, root, root,
     391             :                              group_members, nmembers,
     392           0 :                              &root->group_members);
     393           0 :     if (ret) {
     394           0 :         DEBUG(SSSDBG_OP_FAILURE,
     395             :               "Recursive search failed: %s (%d)\n", strerror(ret), ret);
     396           0 :         goto done;
     397             :     }
     398             : 
     399           0 :     ret = EOK;
     400             : done:
     401           0 :     if (ret == EOK) {
     402           0 :         *res = root;
     403             :     }
     404           0 :     return ret;
     405             : }
     406             : 
     407             : /*=========Nonrecursive search should only show direct parent========== */
     408             : 
     409           0 : static int group_show_trim_memberof(TALLOC_CTX *mem_ctx,
     410             :                                     struct sss_domain_info *domain,
     411             :                                     const char *name,
     412             :                                     const char **memberofs,
     413             :                                     const char ***_direct)
     414             : {
     415             :     struct ldb_dn *dn;
     416             :     char *filter;
     417             :     struct ldb_message **msgs;
     418             :     size_t count;
     419           0 :     const char **direct = NULL;
     420           0 :     int ndirect = 0;
     421             :     int ret;
     422             :     int i;
     423             : 
     424           0 :     dn = sysdb_group_dn(mem_ctx, domain, name);
     425           0 :     if (!dn) {
     426           0 :         return ENOMEM;
     427             :     }
     428             : 
     429           0 :     for (i = 0; memberofs[i]; i++) {
     430             : 
     431           0 :         filter = talloc_asprintf(mem_ctx, "(&(%s=%s)(%s=%s))",
     432           0 :                                  SYSDB_NAME, memberofs[i],
     433             :                                  SYSDB_MEMBER, ldb_dn_get_linearized(dn));
     434           0 :         if (!filter) {
     435           0 :             return ENOMEM;
     436             :         }
     437             : 
     438           0 :         ret = sysdb_search_groups(mem_ctx, domain,
     439             :                                   filter, NULL, &count, &msgs);
     440             :         /* ENOENT is OK, the group is just not a direct parent */
     441           0 :         if (ret != EOK && ret != ENOENT) {
     442           0 :             return ret;
     443             :         }
     444             : 
     445           0 :         if (count > 0) {
     446           0 :             name = ldb_msg_find_attr_as_string(msgs[0],
     447             :                                                SYSDB_NAME, NULL);
     448           0 :             if (!name) {
     449           0 :                 DEBUG(SSSDBG_OP_FAILURE, "Entry %s has no Name Attribute ?!?\n",
     450             :                       ldb_dn_get_linearized(msgs[0]->dn));
     451           0 :                 return EFAULT;
     452             :             }
     453             : 
     454           0 :             direct = talloc_realloc(mem_ctx, direct,
     455             :                                     const char *, ndirect + 2);
     456           0 :             if (!direct) {
     457           0 :                 return ENOMEM;
     458             :             }
     459             : 
     460           0 :             direct[ndirect] = talloc_strdup(direct, name);
     461           0 :             if (!direct[ndirect]) {
     462           0 :                 return ENOMEM;
     463             :             }
     464             : 
     465           0 :             direct[ndirect + 1] = NULL;
     466           0 :             ndirect++;
     467             :         }
     468             :     }
     469             : 
     470           0 :     *_direct = direct;
     471           0 :     return EOK;
     472             : }
     473             : 
     474             : /*==================Recursive search for nested groups================= */
     475             : 
     476           0 : int group_show_recurse(TALLOC_CTX *mem_ctx,
     477             :                        struct sysdb_ctx *sysdb,
     478             :                        struct sss_domain_info *domain,
     479             :                        struct group_info *root,
     480             :                        struct group_info *parent,
     481             :                        const char **group_members,
     482             :                        const int  nmembers,
     483             :                        struct group_info ***up_members)
     484             : {
     485             :     struct group_info **groups;
     486             :     static const char *attrs[] = GROUP_SHOW_ATTRS;
     487             :     struct ldb_message *msg;
     488           0 :     const char **new_group_members = NULL;
     489           0 :     int new_nmembers = 0;
     490             :     int ret;
     491             :     int i;
     492             : 
     493           0 :     groups = talloc_zero_array(root,
     494             :                                struct group_info *,
     495             :                                nmembers+1); /* trailing NULL */
     496             : 
     497           0 :     if (!group_members || !group_members[0]) {
     498           0 :         return ENOENT;
     499             :     }
     500             : 
     501           0 :     for (i = 0; i < nmembers; i++) {
     502             :         /* Skip circular groups */
     503           0 :         if (strcmp(group_members[i], parent->name) == 0) {
     504           0 :             continue;
     505             :         }
     506             : 
     507           0 :         ret = sysdb_search_group_by_name(mem_ctx, domain, group_members[i],
     508             :                                          attrs, &msg);
     509           0 :         if (ret) {
     510           0 :             DEBUG(SSSDBG_OP_FAILURE,
     511             :                   "Search failed: %s (%d)\n", strerror(ret), ret);
     512           0 :             return EIO;
     513             :         }
     514             : 
     515           0 :         ret = process_group(root, sysdb_ctx_get_ldb(sysdb),
     516             :                             msg, domain, parent->name,
     517           0 :                             &groups[i], &new_group_members, &new_nmembers);
     518           0 :         if (ret != EOK) {
     519           0 :             DEBUG(SSSDBG_OP_FAILURE, "Group processing failed: %s (%d)\n",
     520             :                       strerror(ret), ret);
     521           0 :             return ret;
     522             :         }
     523             : 
     524             :         /* descend to another level */
     525           0 :         if (new_nmembers > 0) {
     526           0 :             ret = group_show_recurse(mem_ctx, sysdb, domain,
     527           0 :                                      root, groups[i],
     528             :                                      new_group_members, new_nmembers,
     529             :                                      &parent->group_members);
     530           0 :             if (ret != EOK) {
     531           0 :                 DEBUG(SSSDBG_OP_FAILURE, "Recursive search failed: %s (%d)\n",
     532             :                           strerror(ret), ret);
     533           0 :                 return ret;
     534             :             }
     535           0 :             talloc_zfree(new_group_members);
     536             :         }
     537             :     }
     538             : 
     539           0 :     *up_members = groups;
     540           0 :     return EOK;
     541             : }
     542             : 
     543             : /*==================Get info about MPG================================= */
     544             : 
     545           0 : static int group_show_mpg(TALLOC_CTX *mem_ctx,
     546             :                           struct sss_domain_info *domain,
     547             :                           const char *name,
     548             :                           struct group_info **res)
     549             : {
     550           0 :     const char *attrs[] = GROUP_SHOW_MPG_ATTRS;
     551             :     struct ldb_message *msg;
     552             :     struct group_info *info;
     553             :     int ret;
     554             : 
     555           0 :     info = talloc_zero(mem_ctx, struct group_info);
     556           0 :     if (!info) {
     557           0 :         ret = ENOMEM;
     558           0 :         goto fail;
     559             :     }
     560             : 
     561           0 :     ret = sysdb_search_user_by_name(info, domain, name, attrs, &msg);
     562           0 :     if (ret) {
     563           0 :         DEBUG(SSSDBG_OP_FAILURE,
     564             :               "Search failed: %s (%d)\n", strerror(ret), ret);
     565           0 :         goto fail;
     566             :     }
     567             : 
     568           0 :     info->name = talloc_strdup(info,
     569             :                                ldb_msg_find_attr_as_string(msg,
     570             :                                                            SYSDB_NAME, NULL));
     571           0 :     info->gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0);
     572           0 :     if (info->gid == 0 || info->name == NULL) {
     573           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "No name or no GID?\n");
     574           0 :         ret = EIO;
     575           0 :         goto fail;
     576             :     }
     577           0 :     info->mpg = true;
     578             : 
     579           0 :     *res = info;
     580           0 :     return EOK;
     581             : 
     582             : fail:
     583           0 :     talloc_zfree(info);
     584           0 :     return ret;
     585             : }
     586             : 
     587             : /*==================The main program=================================== */
     588             : 
     589           0 : static void print_group_info(struct group_info *g, int level)
     590             : {
     591             :     int i;
     592             :     char padding[512];
     593             :     char fmt[8];
     594             : 
     595           0 :     snprintf(fmt, 8, "%%%ds", level*PADDING_SPACES);
     596           0 :     snprintf(padding, 512, fmt, "");
     597             : 
     598           0 :     printf(_("%1$s%2$sGroup: %3$s\n"), padding,
     599           0 :                                  g->mpg ? _("Magic Private ") : "",
     600             :                                  g->name);
     601           0 :     printf(_("%1$sGID number: %2$d\n"), padding, g->gid);
     602             : 
     603           0 :     printf(_("%1$sMember users: "), padding);
     604           0 :     if (g->user_members) {
     605           0 :         for (i=0; g->user_members[i]; ++i) {
     606           0 :             printf("%s%s", i>0 ? "," : "",
     607           0 :                            g->user_members[i]);
     608             :         }
     609             :     }
     610           0 :     printf(_("\n%1$sIs a member of: "), padding);
     611           0 :     if (g->memberofs) {
     612           0 :         for (i=0; g->memberofs[i]; ++i) {
     613           0 :             printf("%s%s", i>0 ? "," : "",
     614           0 :                            g->memberofs[i]);
     615             :         }
     616             :     }
     617           0 :     printf(_("\n%1$sMember groups: "), padding);
     618           0 : }
     619             : 
     620           0 : static void print_recursive(struct group_info **group_members, int level)
     621             : {
     622             :     int i;
     623             : 
     624           0 :     if (group_members == NULL) {
     625           0 :         return;
     626             :     }
     627             : 
     628           0 :     level++;
     629           0 :     for (i=0; group_members[i]; ++i) {
     630           0 :         printf("\n");
     631           0 :         print_group_info(group_members[i], level);
     632           0 :         printf("\n");
     633           0 :         print_recursive(group_members[i]->group_members, level);
     634             :     }
     635             : }
     636             : 
     637           0 : int main(int argc, const char **argv)
     638             : {
     639           0 :     int ret = EXIT_SUCCESS;
     640           0 :     int pc_debug = SSSDBG_DEFAULT;
     641           0 :     bool pc_recursive = false;
     642           0 :     const char *pc_groupname = NULL;
     643           0 :     struct tools_ctx *tctx = NULL;
     644           0 :     struct group_info *root = NULL;
     645             :     int i;
     646             : 
     647           0 :     poptContext pc = NULL;
     648           0 :     struct poptOption long_options[] = {
     649             :         POPT_AUTOHELP
     650             :         { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug,
     651           0 :                     0, _("The debug level to run with"), NULL },
     652             :         { "recursive", 'R', POPT_ARG_NONE, NULL, 'r',
     653           0 :             _("Print indirect group members recursively"), NULL },
     654             :         POPT_TABLEEND
     655             :     };
     656             : 
     657           0 :     debug_prg_name = argv[0];
     658             : 
     659           0 :     ret = set_locale();
     660           0 :     if (ret != EOK) {
     661           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     662             :               "set_locale failed (%d): %s\n", ret, strerror(ret));
     663           0 :         ERROR("Error setting the locale\n");
     664           0 :         ret = EXIT_FAILURE;
     665           0 :         goto fini;
     666             :     }
     667             : 
     668             :     /* parse ops_ctx */
     669           0 :     pc = poptGetContext(NULL, argc, argv, long_options, 0);
     670           0 :     poptSetOtherOptionHelp(pc, "GROUPNAME");
     671           0 :     while ((ret = poptGetNextOpt(pc)) > 0) {
     672           0 :         switch (ret) {
     673             :             case 'r':
     674           0 :                 pc_recursive = true;
     675           0 :                 break;
     676             :         }
     677             :     }
     678             : 
     679           0 :     DEBUG_CLI_INIT(pc_debug);
     680             : 
     681           0 :     if (ret != -1) {
     682           0 :         BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini);
     683             :     }
     684             : 
     685           0 :     pc_groupname = poptGetArg(pc);
     686           0 :     if (pc_groupname == NULL) {
     687           0 :         BAD_POPT_PARAMS(pc, _("Specify group to show\n"), ret, fini);
     688             :     }
     689             : 
     690           0 :     CHECK_ROOT(ret, debug_prg_name);
     691             : 
     692           0 :     ret = init_sss_tools(&tctx);
     693           0 :     if (ret != EOK) {
     694           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     695             :               "init_sss_tools failed (%d): %s\n", ret, strerror(ret));
     696           0 :         if (ret == ENOENT) {
     697           0 :             ERROR("Error initializing the tools - no local domain\n");
     698             :         } else {
     699           0 :             ERROR("Error initializing the tools\n");
     700             :         }
     701           0 :         ret = EXIT_FAILURE;
     702           0 :         goto fini;
     703             :     }
     704             : 
     705             :     /* if the domain was not given as part of FQDN, default to local domain */
     706           0 :     ret = parse_name_domain(tctx, pc_groupname);
     707           0 :     if (ret != EOK) {
     708           0 :         ERROR("Invalid domain specified in FQDN\n");
     709           0 :         ret = EXIT_FAILURE;
     710           0 :         goto fini;
     711             :     }
     712             : 
     713             :     /* The search itself */
     714           0 :     ret = group_show(tctx, tctx->sysdb,
     715           0 :                      tctx->local, pc_recursive, tctx->octx->name, &root);
     716             :     /* Also show MPGs */
     717           0 :     if (ret == ENOENT) {
     718           0 :         ret = group_show_mpg(tctx, tctx->local, tctx->octx->name, &root);
     719             :     }
     720             : 
     721             :     /* Process result */
     722           0 :     if (ret) {
     723           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     724             :               "sysdb operation failed (%d)[%s]\n", ret, strerror(ret));
     725           0 :         switch (ret) {
     726             :             case ENOENT:
     727           0 :                 ERROR("No such group in local domain. "
     728             :                       "Printing groups only allowed in local domain.\n");
     729           0 :                 break;
     730             : 
     731             :             default:
     732           0 :                 ERROR("Internal error. Could not print group.\n");
     733           0 :                 break;
     734             :         }
     735           0 :         ret = EXIT_FAILURE;
     736           0 :         goto fini;
     737             :     }
     738             : 
     739             :     /* print the results */
     740           0 :     print_group_info(root, 0);
     741           0 :     if (pc_recursive) {
     742           0 :         printf("\n");
     743           0 :         print_recursive(root->group_members, 0);
     744             :     } else {
     745           0 :         if (root->group_members) {
     746           0 :             for (i=0; root->group_members[i]; ++i) {
     747           0 :                 printf("%s%s", i>0 ? "," : "",
     748           0 :                        root->group_members[i]->name);
     749             :             }
     750             :         }
     751           0 :         printf("\n");
     752             :     }
     753             : 
     754             : fini:
     755           0 :     talloc_free(tctx);
     756           0 :     poptFreeContext(pc);
     757           0 :     exit(ret);
     758             : }

Generated by: LCOV version 1.10