From 4225f9a4bd5eece4d57820bbabb7b882610aa7cc Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 12 Dec 2006 14:52:13 +0000 Subject: r20116: Start merging in the work done to create the new idmap subsystem. Simo. (This used to be commit 50cd8bffeeed2cac755f75fc3d76fe41c451976b) --- source3/utils/net.c | 2 +- source3/utils/net_idmap.c | 375 ++++++++++++++++++++++------------------------ 2 files changed, 177 insertions(+), 200 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net.c b/source3/utils/net.c index 7b97476a25..068af2626f 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -867,7 +867,7 @@ static struct functable net_func[] = { {"SETDOMAINSID", net_setdomainsid}, {"GETDOMAINSID", net_getdomainsid}, {"MAXRID", net_maxrid}, - {"IDMAP", net_idmap}, + {"IDMAP", net_idmap}, {"STATUS", net_status}, {"USERSHARE", net_usershare}, {"USERSIDLIST", net_usersidlist}, diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c index 87da952247..dd16c4b02d 100644 --- a/source3/utils/net_idmap.c +++ b/source3/utils/net_idmap.c @@ -20,166 +20,59 @@ #include "includes.h" #include "utils/net.h" - -/*********************************************************** - Helper function for net_idmap_dump. Dump one entry. - **********************************************************/ -static int net_idmap_dump_one_entry(TDB_CONTEXT *tdb, - TDB_DATA key, - TDB_DATA data, - void *unused) -{ - if (strcmp(key.dptr, "USER HWM") == 0) { - printf("USER HWM %d\n", IVAL(data.dptr,0)); - return 0; - } - - if (strcmp(key.dptr, "GROUP HWM") == 0) { - printf("GROUP HWM %d\n", IVAL(data.dptr,0)); - return 0; - } - - if (strncmp(key.dptr, "S-", 2) != 0) - return 0; - - printf("%s %s\n", data.dptr, key.dptr); - return 0; -} +#define ALLOC_CHECK(mem) do { \ + if (!mem) { \ + d_fprintf(stderr, "Out of memory!\n"); \ + talloc_free(ctx); \ + return -1; \ + } } while(0) /*********************************************************** Dump the current idmap **********************************************************/ static int net_idmap_dump(int argc, const char **argv) { - TDB_CONTEXT *idmap_tdb; - - if ( argc != 1 ) - return net_help_idmap( argc, argv ); - - idmap_tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0); - - if (idmap_tdb == NULL) { - d_fprintf(stderr, "Could not open idmap: %s\n", argv[0]); - return -1; - } - - tdb_traverse(idmap_tdb, net_idmap_dump_one_entry, NULL); - - tdb_close(idmap_tdb); - - return 0; -} - -/*********************************************************** - Fix up the HWMs after a idmap restore. - **********************************************************/ - -struct hwms { - BOOL ok; - uid_t user_hwm; - gid_t group_hwm; -}; - -static int net_idmap_find_max_id(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, - void *handle) -{ - struct hwms *hwms = (struct hwms *)handle; - void *idptr = NULL; - BOOL isgid = False; - int id; + TALLOC_CTX *ctx; + char *filename; - if (strncmp(key.dptr, "S-", 2) != 0) - return 0; - - if (sscanf(data.dptr, "GID %d", &id) == 1) { - idptr = (void *)&hwms->group_hwm; - isgid = True; - } - - if (sscanf(data.dptr, "UID %d", &id) == 1) { - idptr = (void *)&hwms->user_hwm; - isgid = False; + if (argc != 1) { + return net_help_idmap(argc, argv); } - if (idptr == NULL) { - d_fprintf(stderr, "Illegal idmap entry: [%s]->[%s]\n", - key.dptr, data.dptr); - hwms->ok = False; + if (! winbind_ping()) { + d_fprintf(stderr, "To use net idmap Winbindd must be running.\n"); return -1; } - if (isgid) { - if (hwms->group_hwm <= (gid_t)id) { - hwms->group_hwm = (gid_t)(id+1); + ctx = talloc_new(NULL); + ALLOC_CHECK(ctx); + + filename = talloc_strdup(ctx, argv[0]); + ALLOC_CHECK(filename); + + /* filename must be absolute */ + if (*filename != '/') { + char path[4096]; + + filename = getcwd(path, 4095); + if ( ! filename) { + d_fprintf(stderr, "Failed to obtain full output file path"); + talloc_free(ctx); + return -1; } - } else { - if (hwms->user_hwm <= (uid_t)id) { - hwms->user_hwm = (uid_t)(id+1); - } - } - - return 0; -} -static NTSTATUS net_idmap_fixup_hwm(void) -{ - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - TDB_CONTEXT *idmap_tdb; - char *tdbfile = NULL; - - struct hwms hwms; - struct hwms highest; - - if (!lp_idmap_uid(&hwms.user_hwm, &highest.user_hwm) || - !lp_idmap_gid(&hwms.group_hwm, &highest.group_hwm)) { - d_fprintf(stderr, "idmap range missing\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - tdbfile = SMB_STRDUP(lock_path("winbindd_idmap.tdb")); - if (!tdbfile) { - DEBUG(0, ("idmap_init: out of memory!\n")); - return NT_STATUS_NO_MEMORY; - } - - idmap_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0); - - if (idmap_tdb == NULL) { - d_fprintf(stderr, "Could not open idmap: %s\n", tdbfile); - return NT_STATUS_NO_SUCH_FILE; - } - - hwms.ok = True; - - tdb_traverse(idmap_tdb, net_idmap_find_max_id, &hwms); - - if (!hwms.ok) { - goto done; + filename = talloc_asprintf(ctx, "%s/%s", path, argv[0]); + ALLOC_CHECK(filename); } - d_printf("USER HWM: %d GROUP HWM: %d\n", - hwms.user_hwm, hwms.group_hwm); - - if (hwms.user_hwm >= highest.user_hwm) { - d_fprintf(stderr, "Highest UID out of uid range\n"); - goto done; - } - - if (hwms.group_hwm >= highest.group_hwm) { - d_fprintf(stderr, "Highest GID out of gid range\n"); - goto done; - } - - if ((tdb_store_int32(idmap_tdb, "USER HWM", (int32)hwms.user_hwm) != 0) || - (tdb_store_int32(idmap_tdb, "GROUP HWM", (int32)hwms.group_hwm) != 0)) { - d_fprintf(stderr, "Could not store HWMs\n"); - goto done; + if ( ! winbind_idmap_dump_maps(ctx, filename)) { + d_fprintf(stderr, "Failed to obtain idmap data from winbindd\n"); + talloc_free(ctx); + return -1; } - result = NT_STATUS_OK; - done: - tdb_close(idmap_tdb); - return result; + talloc_free(ctx); + return 0; } /*********************************************************** @@ -188,20 +81,31 @@ static NTSTATUS net_idmap_fixup_hwm(void) static int net_idmap_restore(int argc, const char **argv) { - if (!idmap_init(lp_idmap_backend())) { - d_fprintf(stderr, "Could not init idmap\n"); + TALLOC_CTX *ctx; + FILE *input; + + if (! winbind_ping()) { + d_fprintf(stderr, "To use net idmap Winbindd must be running.\n"); return -1; } - while (!feof(stdin)) { - fstring line, sid_string, fmt_string1, fmt_string2; + ctx = talloc_new(NULL); + ALLOC_CHECK(ctx); + + if (argc == 1) { + input = fopen(argv[0], "r"); + } else { + input = stdin; + } + + while (!feof(input)) { + char line[128], sid_string[128]; int len; - unid_t id; - enum idmap_type type; - unsigned long idval; DOM_SID sid; + struct id_map map; + unsigned long idval; - if (fgets(line, sizeof(line)-1, stdin) == NULL) + if (fgets(line, 127, input) == NULL) break; len = strlen(line); @@ -209,39 +113,50 @@ static int net_idmap_restore(int argc, const char **argv) if ( (len > 0) && (line[len-1] == '\n') ) line[len-1] = '\0'; - snprintf(fmt_string1, sizeof(fmt_string1), "GID %%ul %%%us", FSTRING_LEN); - snprintf(fmt_string2, sizeof(fmt_string2), "UID %%ul %%%us", FSTRING_LEN); - - if (sscanf(line, fmt_string1, &idval, sid_string) == 2) { - type = ID_GROUPID; - id.gid = (gid_t)idval; - } else if (sscanf(line, fmt_string2, &idval, sid_string) == 2) { - type = ID_USERID; - id.uid = (uid_t)idval; + 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_printf("ignoring invalid line [%s]\n", line); + d_fprintf(stderr, "ignoring invalid line [%s]\n", line); continue; } if (!string_to_sid(&sid, sid_string)) { - d_printf("ignoring invalid sid [%s]\n", sid_string); + d_fprintf(stderr, "ignoring invalid sid [%s]\n", sid_string); continue; } + map.sid = &sid; - if (!NT_STATUS_IS_OK(idmap_set_mapping(&sid, id, type))) { + if (!winbind_set_mapping(&map)) { d_fprintf(stderr, "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)); + (map.xid.type == ID_TYPE_GID) ? "GID" : "UID", + (unsigned long)map.xid.id, sid_string_static(map.sid)); continue; } - + } - idmap_close(); + if (input != stdin) { + fclose(input); + } - return NT_STATUS_IS_OK(net_idmap_fixup_hwm()) ? 0 : -1; + talloc_free(ctx); + return 0; } /*********************************************************** @@ -249,62 +164,122 @@ static int net_idmap_restore(int argc, const char **argv) **********************************************************/ static int net_idmap_delete(int argc, const char **argv) { - TDB_CONTEXT *idmap_tdb; - TDB_DATA key, data; - fstring sid; - - if (argc != 2) - return net_help_idmap(argc, argv); + d_printf("Not Implemented yet\n"); + return -1; +} - idmap_tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDWR, 0); +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 (idmap_tdb == NULL) { - d_fprintf(stderr, "Could not open idmap: %s\n", argv[0]); - return -1; + if (alloc) { + r = asprintf(&tmp, "IDMAP_ALLOC_%s", backend); + } else { + r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain); } - fstrcpy(sid, argv[1]); + if (r < 0) return false; - if (strncmp(sid, "S-1-5-", strlen("S-1-5-")) != 0) { - d_fprintf(stderr, "Can only delete SIDs, %s is does not start with " - "S-1-5-\n", sid); - return -1; + strupper_m(tmp); /* make sure the key is case insensitive */ + ret = secrets_store_generic(tmp, identity, secret); + + free(tmp); + return ret; +} + + +static int net_idmap_secret(int argc, const char **argv) +{ + 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); } - key.dptr = sid; - key.dsize = strlen(key.dptr)+1; + secret = argv[1]; - data = tdb_fetch(idmap_tdb, key); + ctx = talloc_new(NULL); + ALLOC_CHECK(ctx); - if (data.dptr == NULL) { - d_fprintf(stderr, "Could not find sid %s\n", argv[1]); - return -1; + if (strcmp(argv[0], "alloc") == 0) { + domain = NULL; + backend = lp_idmap_alloc_backend(); + } else { + domain = talloc_strdup(ctx, argv[0]); + ALLOC_CHECK(domain); + + opt = talloc_asprintf(ctx, "idmap config %s", domain); + ALLOC_CHECK(opt); + + backend = talloc_strdup(ctx, lp_parm_const_string(-1, opt, "backend", "tdb")); + ALLOC_CHECK(backend); } - if (tdb_delete(idmap_tdb, key) != 0) { - d_fprintf(stderr, "Could not delete key %s\n", argv[1]); + if ( ( ! backend) || ( ! strequal(backend, "ldap"))) { + d_fprintf(stderr, "The only currently supported backend is LDAP\n"); + talloc_free(ctx); return -1; } - if (tdb_delete(idmap_tdb, data) != 0) { - d_fprintf(stderr, "Could not delete key %s\n", data.dptr); + if (domain) { + + 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; + } + + 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; + } + + ret = idmap_store_secret("ldap", true, NULL, dn, secret); + } + + if ( ! ret) { + d_fprintf(stderr, "Failed to store secret\n"); + talloc_free(ctx); return -1; } + d_printf("Secret stored\n"); return 0; } - int net_help_idmap(int argc, const char **argv) { - d_printf("net idmap dump "\ - "\n Dump current id mapping\n"); + d_printf("net idmap dump \n"\ + " Dump current id mapping\n"); - d_printf("net idmap restore"\ - "\n Restore entries from stdin to current local idmap\n"); + d_printf("net idmap restore\n"\ + " Restore entries from stdin\n"); /* Deliberately *not* document net idmap delete */ + d_printf("net idmap secret |alloc \n"\ + " Set the secret for the specified DOMAIN (or the alloc module)\n"); + return -1; } @@ -316,7 +291,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} }; -- cgit