r23612: Revert 'net idmap dump' to the 3.0.24 behaviour.
[ira/wip.git] / source3 / utils / net_idmap.c
index f5b4bf1b4a74c2906daec168ff7a2d11d12686c7..d4d2c931b84eb6262d92bbf60651e57fb0209e84 100644 (file)
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "includes.h"
-#include "../utils/net.h"
+#include "utils/net.h"
 
+#define ALLOC_CHECK(mem) do { \
+       if (!mem) { \
+               d_fprintf(stderr, "Out of memory!\n"); \
+               talloc_free(ctx); \
+               return -1; \
+       } } while(0)
 
 /***********************************************************
  Helper function for net_idmap_dump. Dump one entry.
@@ -29,17 +35,17 @@ static int net_idmap_dump_one_entry(TDB_CONTEXT *tdb,
                                    TDB_DATA data,
                                    void *unused)
 {
-       if (strcmp(key.dptr, "USER HWM") == 0) {
+       if (strcmp((char *)key.dptr, "USER HWM") == 0) {
                printf("USER HWM %d\n", IVAL(data.dptr,0));
                return 0;
        }
 
-       if (strcmp(key.dptr, "GROUP HWM") == 0) {
+       if (strcmp((char *)key.dptr, "GROUP HWM") == 0) {
                printf("GROUP HWM %d\n", IVAL(data.dptr,0));
                return 0;
        }
 
-       if (strncmp(key.dptr, "S-", 2) != 0)
+       if (strncmp((char *)key.dptr, "S-", 2) != 0)
                return 0;
 
        printf("%s %s\n", data.dptr, key.dptr);
@@ -59,7 +65,7 @@ static int net_idmap_dump(int argc, const char **argv)
        idmap_tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0);
 
        if (idmap_tdb == NULL) {
-               d_printf("Could not open idmap: %s\n", argv[0]);
+               d_fprintf(stderr, "Could not open idmap: %s\n", argv[0]);
                return -1;
        }
 
@@ -71,177 +77,209 @@ static int net_idmap_dump(int argc, const char **argv)
 }
 
 /***********************************************************
- Fix up the HWMs after a idmap restore.
+ Write entries from stdin to current local idmap
  **********************************************************/
 
-struct hwms {
-       BOOL ok;
-       int user_hwm;
-       int group_hwm;
-};
-
-static int net_idmap_find_max_id(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data,
-                                void *handle)
+static int net_idmap_restore(int argc, const char **argv)
 {
-       struct hwms *hwms = (struct hwms *)handle;
-       int *idptr = NULL;
-       int id;
-
-       if (strncmp(key.dptr, "S-", 2) != 0)
-               return 0;
+       TALLOC_CTX *ctx;
+       FILE *input;
 
-       if (sscanf(data.dptr, "GID %d", &id) == 1) {
-               idptr = &hwms->group_hwm;
+       if (! winbind_ping()) {
+               d_fprintf(stderr, "To use net idmap Winbindd must be running.\n");
+               return -1;
        }
 
-       if (sscanf(data.dptr, "UID %d", &id) == 1) {
-               idptr = &hwms->user_hwm;
-       }
+       ctx = talloc_new(NULL);
+       ALLOC_CHECK(ctx);
 
-       if (idptr == NULL) {
-               d_printf("Illegal idmap entry: [%s]->[%s]\n",
-                        key.dptr, data.dptr);
-               hwms->ok = False;
-               return -1;
+       if (argc == 1) {
+               input = fopen(argv[0], "r");
+       } else {
+               input = stdin;
        }
 
-       if (*idptr <= id)
-               *idptr = id+1;
-
-       return 0;
-}
+       while (!feof(input)) {
+               char line[128], sid_string[128];
+               int len;
+               DOM_SID sid;
+               struct id_map map;
+               unsigned long idval;
 
-static NTSTATUS net_idmap_fixup_hwm(void)
-{
-       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       TDB_CONTEXT *idmap_tdb;
-       char *tdbfile = NULL;
+               if (fgets(line, 127, input) == NULL)
+                       break;
 
-       struct hwms hwms;
-       struct hwms highest;
+               len = strlen(line);
 
-       if (!lp_idmap_uid(&hwms.user_hwm, &highest.user_hwm) ||
-           !lp_idmap_gid(&hwms.group_hwm, &highest.group_hwm)) {
-               d_printf("idmap range missing\n");
-               return NT_STATUS_UNSUCCESSFUL;
-       }
+               if ( (len > 0) && (line[len-1] == '\n') )
+                       line[len-1] = '\0';
 
-       tdbfile = strdup(lock_path("winbindd_idmap.tdb"));
-       if (!tdbfile) {
-               DEBUG(0, ("idmap_init: out of memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
+               if (sscanf(line, "GID %lu %128s", &idval, sid_string) == 2) {
+                       map.xid.type = ID_TYPE_GID;
+                       map.xid.id = idval;
+               } else if (sscanf(line, "UID %lu %128s", &idval, sid_string) == 2) {
+                       map.xid.type = ID_TYPE_UID;
+                       map.xid.id = idval;
+               } else if (sscanf(line, "USER HWM %lu", &idval) == 1) {
+                       /* set uid hwm */
+                       if (! winbind_set_uid_hwm(idval)) {
+                               d_fprintf(stderr, "Could not set USER HWM\n");
+                       }
+                       continue;
+               } else if (sscanf(line, "GROUP HWM %lu", &idval) == 1) {
+                       /* set gid hwm */
+                       if (! winbind_set_gid_hwm(idval)) {
+                               d_fprintf(stderr, "Could not set GROUP HWM\n");
+                       }
+                       continue;
+               } else {
+                       d_fprintf(stderr, "ignoring invalid line [%s]\n", line);
+                       continue;
+               }
 
-       idmap_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0);
+               if (!string_to_sid(&sid, sid_string)) {
+                       d_fprintf(stderr, "ignoring invalid sid [%s]\n", sid_string);
+                       continue;
+               }
+               map.sid = &sid;
 
-       if (idmap_tdb == NULL) {
-               d_printf("Could not open idmap: %s\n", tdbfile);
-               return NT_STATUS_NO_SUCH_FILE;
+               if (!winbind_set_mapping(&map)) {
+                       d_fprintf(stderr, "Could not set mapping of %s %lu to sid %s\n",
+                                (map.xid.type == ID_TYPE_GID) ? "GID" : "UID",
+                                (unsigned long)map.xid.id, sid_string_static(map.sid));
+                       continue;
+               }
+                        
        }
 
-       hwms.ok = True;
-
-       tdb_traverse(idmap_tdb, net_idmap_find_max_id, &hwms);
-
-       if (!hwms.ok) {
-               goto done;
+       if (input != stdin) {
+               fclose(input);
        }
 
-       d_printf("USER HWM: %d  GROUP HWM: %d\n",
-                hwms.user_hwm, hwms.group_hwm);
+       talloc_free(ctx);
+       return 0;
+}
 
-       if (hwms.user_hwm >= highest.user_hwm) {
-               d_printf("Highest UID out of uid range\n");
-               goto done;
-       }
+/***********************************************************
+ Delete a SID mapping from a winbindd_idmap.tdb
+ **********************************************************/
+static int net_idmap_delete(int argc, const char **argv)
+{
+       d_printf("Not Implemented yet\n");
+       return -1;
+}
 
-       if (hwms.group_hwm >= highest.group_hwm) {
-               d_printf("Highest GID out of gid range\n");
-               goto done;
+static int net_idmap_set(int argc, const char **argv)
+{
+       d_printf("Not Implemented yet\n");
+       return -1;
+}
+BOOL idmap_store_secret(const char *backend, bool alloc,
+                       const char *domain, const char *identity,
+                       const char *secret)
+{
+       char *tmp;
+       int r;
+       BOOL ret;
+
+       if (alloc) {
+               r = asprintf(&tmp, "IDMAP_ALLOC_%s", backend);
+       } else {
+               r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
        }
 
-       if ((tdb_store_int32(idmap_tdb, "USER HWM", hwms.user_hwm) != 0) ||
-           (tdb_store_int32(idmap_tdb, "GROUP HWM", hwms.group_hwm) != 0)) {
-               d_printf("Could not store HWMs\n");
-               goto done;
-       }
+       if (r < 0) return false;
 
-       result = NT_STATUS_OK;
- done:
-       tdb_close(idmap_tdb);
-       return result;
+       strupper_m(tmp); /* make sure the key is case insensitive */
+       ret = secrets_store_generic(tmp, identity, secret);
+
+       free(tmp);
+       return ret;
 }
 
-/***********************************************************
- Write entries from stdin to current local idmap
- **********************************************************/
-static int net_idmap_restore(int argc, const char **argv)
+
+static int net_idmap_secret(int argc, const char **argv)
 {
-       if (!idmap_init(lp_idmap_backend())) {
-               d_printf("Could not init idmap\n");
-               return -1;
+       TALLOC_CTX *ctx;
+       const char *secret;
+       const char *dn;
+       char *domain;
+       char *backend;
+       char *opt = NULL;
+       BOOL ret;
+
+       if (argc != 2) {
+               return net_help_idmap(argc, argv);
        }
 
-       while (!feof(stdin)) {
-               fstring line, sid_string;
-               int len;
-               unid_t id;
-               int type = ID_EMPTY;
-               DOM_SID sid;
-
-               if (fgets(line, sizeof(line)-1, stdin) == NULL)
-                       break;
+       secret = argv[1];
 
-               len = strlen(line);
+       ctx = talloc_new(NULL);
+       ALLOC_CHECK(ctx);
 
-               if ( (len > 0) && (line[len-1] == '\n') )
-                       line[len-1] = '\0';
+       if (strcmp(argv[0], "alloc") == 0) {
+               domain = NULL;
+               backend = lp_idmap_alloc_backend();
+       } else {
+               domain = talloc_strdup(ctx, argv[0]);
+               ALLOC_CHECK(domain);
 
-               /* Yuck - this is broken for sizeof(gid_t) != sizeof(int) */
+               opt = talloc_asprintf(ctx, "idmap config %s", domain);
+               ALLOC_CHECK(opt);
 
-               if (sscanf(line, "GID %d %s", &id.gid, sid_string) == 2) {
-                       type = ID_GROUPID;
-               }
+               backend = talloc_strdup(ctx, lp_parm_const_string(-1, opt, "backend", "tdb"));
+               ALLOC_CHECK(backend);
+       }
 
-               /* Yuck - this is broken for sizeof(uid_t) != sizeof(int) */
+       if ( ( ! backend) || ( ! strequal(backend, "ldap"))) {
+               d_fprintf(stderr, "The only currently supported backend is LDAP\n");
+               talloc_free(ctx);
+               return -1;
+       }
 
-               if (sscanf(line, "UID %d %s", &id.uid, sid_string) == 2) {
-                       type = ID_USERID;
-               }
+       if (domain) {
 
-               if (type == ID_EMPTY) {
-                       d_printf("ignoring invalid line [%s]\n", line);
-                       continue;
+               dn = lp_parm_const_string(-1, opt, "ldap_user_dn", NULL);
+               if ( ! dn) {
+                       d_fprintf(stderr, "Missing ldap_user_dn option for domain %s\n", domain);
+                       talloc_free(ctx);
+                       return -1;
                }
 
-               if (!string_to_sid(&sid, sid_string)) {
-                       d_printf("ignoring invalid sid [%s]\n", sid_string);
-                       continue;
+               ret = idmap_store_secret("ldap", false, domain, dn, secret);
+       } else {
+               dn = lp_parm_const_string(-1, "idmap alloc config", "ldap_user_dn", NULL);
+               if ( ! dn) {
+                       d_fprintf(stderr, "Missing ldap_user_dn option for alloc backend\n");
+                       talloc_free(ctx);
+                       return -1;
                }
 
-               if (!NT_STATUS_IS_OK(idmap_set_mapping(&sid, id, type))) {
-                       d_printf("Could not set mapping of %s %lu to sid %s\n",
-                                (type == ID_GROUPID) ? "GID" : "UID",
-                                (type == ID_GROUPID) ? (unsigned long)id.gid:
-                                (unsigned long)id.uid, 
-                                sid_string_static(&sid));
-                       continue;
-               }
-                                
+               ret = idmap_store_secret("ldap", true, NULL, dn, secret);
        }
 
-       idmap_close();
+       if ( ! ret) {
+               d_fprintf(stderr, "Failed to store secret\n");
+               talloc_free(ctx);
+               return -1;
+       }
 
-       return NT_STATUS_IS_OK(net_idmap_fixup_hwm()) ? 0 : -1;
+       d_printf("Secret stored\n");
+       return 0;
 }
 
 int net_help_idmap(int argc, const char **argv)
 {
-       d_printf("net idmap dump filename"\
-                "\n  Dump current id mapping\n");
+       d_printf("net idmap dump <outputfile>\n"\
+                "    Dump current id mapping\n");
+
+       d_printf("net idmap restore\n"\
+                "    Restore entries from stdin\n");
+
+       /* Deliberately *not* document net idmap delete */
 
-       d_printf("net idmap restore"\
-                "\n  Restore entries from stdin to current local idmap\n");
+       d_printf("net idmap secret <DOMAIN>|alloc <secret>\n"\
+                "    Set the secret for the specified DOMAIN (or the alloc module)\n");
 
        return -1;
 }
@@ -254,6 +292,9 @@ int net_idmap(int argc, const char **argv)
        struct functable func[] = {
                {"dump", net_idmap_dump},
                {"restore", net_idmap_restore},
+               {"setmap", net_idmap_set },
+               {"delete", net_idmap_delete},
+               {"secret", net_idmap_secret},
                {"help", net_help_idmap},
                {NULL, NULL}
        };