>From 6fed9c8c4329fd74bbbe1528b6870060db4e6d30 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Fri, 21 Aug 2009 11:18:49 +0200
Subject: [PATCH] Disallow all operations outside domains, fix deleting cache for files

One of the previous patches disallowed adding users and groups outside
known domains but it was missing disallowing modifying, deleting, etc.

Also don't error if there's no sysdb cache to delete after deleting
legacy user/domain.

Fixes: tickets #113,#114
---
 server/tools/sss_groupdel.c |   21 ++++++++++++++++-----
 server/tools/sss_groupmod.c |    6 +++++-
 server/tools/sss_userdel.c  |   19 +++++++++++++++----
 server/tools/sss_usermod.c  |    6 +++++-
 4 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/server/tools/sss_groupdel.c b/server/tools/sss_groupdel.c
index 9678208..1cf9ed0 100644
--- a/server/tools/sss_groupdel.c
+++ b/server/tools/sss_groupdel.c
@@ -148,6 +148,7 @@ int main(int argc, const char **argv)
     struct sss_domain_info *dom;
     struct group *grp_info;
     const char *pc_groupname = NULL;
+    enum id_domain domain_type;
 
     poptContext pc = NULL;
     struct poptOption long_options[] = {
@@ -232,13 +233,12 @@ int main(int argc, const char **argv)
         data->domain = dom;
     }
 
-    ret = get_domain_type(data->ctx, data->domain);
-    switch (ret) {
+    domain_type = get_domain_type(data->ctx, data->domain);
+    switch (domain_type) {
         case ID_IN_LOCAL:
             break;
 
         case ID_IN_LEGACY_LOCAL:
-        case ID_OUTSIDE:
             ret = groupdel_legacy(data);
             if(ret != EOK) {
                 ERROR("Cannot delete group from domain using the legacy tools\n");
@@ -247,6 +247,11 @@ int main(int argc, const char **argv)
             }
             break; /* Also delete possible cached entries in sysdb */
 
+        case ID_OUTSIDE:
+            ERROR("The selected GID is outside all domain ranges\n");
+            ret = EXIT_FAILURE;
+            goto fini;
+
         case ID_IN_OTHER:
             DEBUG(1, ("Cannot remove group from domain %s\n", dom->name));
             ERROR("Unsupported domain type\n");
@@ -254,7 +259,7 @@ int main(int argc, const char **argv)
             goto fini;
 
         default:
-            DEBUG(1, ("Unknown return code %d from get_domain_type\n", ret));
+            DEBUG(1, ("Unknown return code %d from get_domain_type\n", domain_type));
             ERROR("Error looking up domain\n");
             ret = EXIT_FAILURE;
             goto fini;
@@ -279,7 +284,13 @@ int main(int argc, const char **argv)
         DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret)));
         switch (ret) {
             case ENOENT:
-                ERROR("No such group\n");
+                /* if we got ENOENT after deleting group from legacy domain
+                 * that just means there was no cached entry to delete */
+                if (domain_type == ID_IN_LEGACY_LOCAL) {
+                    ret = EXIT_SUCCESS;
+                    goto fini;
+                }
+                ERROR("No such user\n");
                 break;
 
             default:
diff --git a/server/tools/sss_groupmod.c b/server/tools/sss_groupmod.c
index 175d08d..cca9abc 100644
--- a/server/tools/sss_groupmod.c
+++ b/server/tools/sss_groupmod.c
@@ -439,13 +439,17 @@ int main(int argc, const char **argv)
             break;
 
         case ID_IN_LEGACY_LOCAL:
-        case ID_OUTSIDE:
             ret = groupmod_legacy(ctx, data, data->domain);
             if(ret != EOK) {
                 ERROR("Cannot delete group from domain using the legacy tools\n");
             }
             goto fini;
 
+        case ID_OUTSIDE:
+            ERROR("The selected GID is outside all domain ranges\n");
+            ret = EXIT_FAILURE;
+            goto fini;
+
         case ID_IN_OTHER:
             DEBUG(1, ("Cannot modify group from domain %s\n", dom->name));
             ERROR("Unsupported domain type\n");
diff --git a/server/tools/sss_userdel.c b/server/tools/sss_userdel.c
index be35b4f..7c796bb 100644
--- a/server/tools/sss_userdel.c
+++ b/server/tools/sss_userdel.c
@@ -148,6 +148,7 @@ int main(int argc, const char **argv)
     struct sss_domain_info *dom;
     struct passwd *pwd_info;
     const char *pc_username = NULL;
+    enum id_domain domain_type;
 
     int pc_debug = 0;
     poptContext pc = NULL;
@@ -232,13 +233,12 @@ int main(int argc, const char **argv)
         data->domain = dom;
     }
 
-    ret = get_domain_type(data->ctx, data->domain);
-    switch (ret) {
+    domain_type = get_domain_type(data->ctx, data->domain);
+    switch (domain_type) {
         case ID_IN_LOCAL:
             break;
 
         case ID_IN_LEGACY_LOCAL:
-        case ID_OUTSIDE:
             ret = userdel_legacy(data);
             if(ret != EOK) {
                 ERROR("Cannot delete user from domain using the legacy tools\n");
@@ -247,6 +247,11 @@ int main(int argc, const char **argv)
             }
             break; /* Also delete possible cached entries in sysdb */
 
+        case ID_OUTSIDE:
+            ERROR("The selected UID is outside all domain ranges\n");
+            ret = EXIT_FAILURE;
+            goto fini;
+
         case ID_IN_OTHER:
             DEBUG(1, ("Cannot remove user from domain %s\n", dom->name));
             ERROR("Unsupported domain type\n");
@@ -254,7 +259,7 @@ int main(int argc, const char **argv)
             goto fini;
 
         default:
-            DEBUG(1, ("Unknown return code %d from get_domain_type\n", ret));
+            DEBUG(1, ("Unknown return code %d from get_domain_type\n", domain_type));
             ERROR("Error looking up domain\n");
             ret = EXIT_FAILURE;
             goto fini;
@@ -279,6 +284,12 @@ int main(int argc, const char **argv)
         DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret)));
         switch (ret) {
             case ENOENT:
+                /* if we got ENOENT after deleting user from legacy domain
+                 * that just means there was no cached entry to delete */
+                if (domain_type == ID_IN_LEGACY_LOCAL) {
+                    ret = EXIT_SUCCESS;
+                    goto fini;
+                }
                 ERROR("No such user\n");
                 break;
 
diff --git a/server/tools/sss_usermod.c b/server/tools/sss_usermod.c
index 0e1055d..1dfd2a7 100644
--- a/server/tools/sss_usermod.c
+++ b/server/tools/sss_usermod.c
@@ -504,7 +504,6 @@ int main(int argc, const char **argv)
             break;
 
         case ID_IN_LEGACY_LOCAL:
-        case ID_OUTSIDE:
             ret = usermod_legacy(ctx, data, pc_uid, pc_gid, pc_gecos,
                                  pc_home, pc_shell, pc_lock, data->domain);
             if(ret != EOK) {
@@ -512,6 +511,11 @@ int main(int argc, const char **argv)
             }
             goto fini;
 
+        case ID_OUTSIDE:
+            ERROR("The selected UID is outside all domain ranges\n");
+            ret = EXIT_FAILURE;
+            goto fini;
+
         case ID_IN_OTHER:
             DEBUG(1, ("Cannot modify user from domain %s\n", dom->name));
             ERROR("Unsupported domain type\n");
-- 
1.6.2.5

