r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need
[samba.git] / source3 / utils / net_idmap.c
index 61ef919b849ab87c492670d81c5fa2f2559f9c54..87da952247ae839ce044045f9e36d5da5b93a335 100644 (file)
@@ -18,7 +18,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "includes.h"
-#include "../utils/net.h"
+#include "utils/net.h"
 
 
 /***********************************************************
@@ -59,7 +59,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;
        }
 
@@ -76,37 +76,47 @@ static int net_idmap_dump(int argc, const char **argv)
 
 struct hwms {
        BOOL ok;
-       int user_hwm;
-       int group_hwm;
+       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;
-       int *idptr = NULL;
+       void *idptr = NULL;
+       BOOL isgid = False;
        int id;
 
        if (strncmp(key.dptr, "S-", 2) != 0)
                return 0;
 
        if (sscanf(data.dptr, "GID %d", &id) == 1) {
-               idptr = &hwms->group_hwm;
+               idptr = (void *)&hwms->group_hwm;
+               isgid = True;
        }
 
        if (sscanf(data.dptr, "UID %d", &id) == 1) {
-               idptr = &hwms->user_hwm;
+               idptr = (void *)&hwms->user_hwm;
+               isgid = False;
        }
 
        if (idptr == NULL) {
-               d_printf("Illegal idmap entry: [%s]->[%s]\n",
+               d_fprintf(stderr, "Illegal idmap entry: [%s]->[%s]\n",
                         key.dptr, data.dptr);
                hwms->ok = False;
                return -1;
        }
 
-       if (*idptr <= id)
-               *idptr = id+1;
+       if (isgid) {
+               if (hwms->group_hwm <= (gid_t)id) {
+                       hwms->group_hwm = (gid_t)(id+1);
+               }
+       } else {
+               if (hwms->user_hwm <= (uid_t)id) {
+                       hwms->user_hwm = (uid_t)(id+1);
+               }
+       }
 
        return 0;
 }
@@ -116,18 +126,17 @@ static NTSTATUS net_idmap_fixup_hwm(void)
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        TDB_CONTEXT *idmap_tdb;
        char *tdbfile = NULL;
-       int dummy;
 
        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_printf("idmap range missing\n");
+               d_fprintf(stderr, "idmap range missing\n");
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       tdbfile = strdup(lock_path("winbindd_idmap.tdb"));
+       tdbfile = SMB_STRDUP(lock_path("winbindd_idmap.tdb"));
        if (!tdbfile) {
                DEBUG(0, ("idmap_init: out of memory!\n"));
                return NT_STATUS_NO_MEMORY;
@@ -136,7 +145,7 @@ static NTSTATUS net_idmap_fixup_hwm(void)
        idmap_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0);
 
        if (idmap_tdb == NULL) {
-               d_printf("Could not open idmap: %s\n", tdbfile);
+               d_fprintf(stderr, "Could not open idmap: %s\n", tdbfile);
                return NT_STATUS_NO_SUCH_FILE;
        }
 
@@ -152,18 +161,18 @@ static NTSTATUS net_idmap_fixup_hwm(void)
                 hwms.user_hwm, hwms.group_hwm);
 
        if (hwms.user_hwm >= highest.user_hwm) {
-               d_printf("Highest UID out of uid range\n");
+               d_fprintf(stderr, "Highest UID out of uid range\n");
                goto done;
        }
 
        if (hwms.group_hwm >= highest.group_hwm) {
-               d_printf("Highest GID out of gid range\n");
+               d_fprintf(stderr, "Highest GID out of gid range\n");
                goto done;
        }
 
-       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");
+       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;
        }
 
@@ -176,18 +185,20 @@ static NTSTATUS net_idmap_fixup_hwm(void)
 /***********************************************************
  Write entries from stdin to current local idmap
  **********************************************************/
+
 static int net_idmap_restore(int argc, const char **argv)
 {
        if (!idmap_init(lp_idmap_backend())) {
-               d_printf("Could not init idmap\n");
+               d_fprintf(stderr, "Could not init idmap\n");
                return -1;
        }
 
        while (!feof(stdin)) {
-               fstring line, sid_string;
+               fstring line, sid_string, fmt_string1, fmt_string2;
                int len;
                unid_t id;
-               int type = ID_EMPTY;
+               enum idmap_type type;
+               unsigned long idval;
                DOM_SID sid;
 
                if (fgets(line, sizeof(line)-1, stdin) == NULL)
@@ -198,19 +209,16 @@ static int net_idmap_restore(int argc, const char **argv)
                if ( (len > 0) && (line[len-1] == '\n') )
                        line[len-1] = '\0';
 
-               /* Yuck - this is broken for sizeof(gid_t) != sizeof(int) */
+               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, "GID %d %s", &id.gid, sid_string) == 2) {
+               if (sscanf(line, fmt_string1, &idval, sid_string) == 2) {
                        type = ID_GROUPID;
-               }
-
-               /* Yuck - this is broken for sizeof(uid_t) != sizeof(int) */
-
-               if (sscanf(line, "UID %d %s", &id.uid, sid_string) == 2) {
+                       id.gid = (gid_t)idval;
+               } else if (sscanf(line, fmt_string2, &idval, sid_string) == 2) {
                        type = ID_USERID;
-               }
-
-               if (type == ID_EMPTY) {
+                       id.uid = (uid_t)idval;
+               } else {
                        d_printf("ignoring invalid line [%s]\n", line);
                        continue;
                }
@@ -221,7 +229,7 @@ static int net_idmap_restore(int argc, const char **argv)
                }
 
                if (!NT_STATUS_IS_OK(idmap_set_mapping(&sid, id, type))) {
-                       d_printf("Could not set mapping of %s %lu to sid %s\n",
+                       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, 
@@ -236,14 +244,67 @@ static int net_idmap_restore(int argc, const char **argv)
        return NT_STATUS_IS_OK(net_idmap_fixup_hwm()) ? 0 : -1;
 }
 
+/***********************************************************
+ Delete a SID mapping from a winbindd_idmap.tdb
+ **********************************************************/
+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);
+
+       idmap_tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDWR, 0);
+
+       if (idmap_tdb == NULL) {
+               d_fprintf(stderr, "Could not open idmap: %s\n", argv[0]);
+               return -1;
+       }
+
+       fstrcpy(sid, argv[1]);
+
+       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;
+       }
+
+       key.dptr = sid;
+       key.dsize = strlen(key.dptr)+1;
+
+       data = tdb_fetch(idmap_tdb, key);
+
+       if (data.dptr == NULL) {
+               d_fprintf(stderr, "Could not find sid %s\n", argv[1]);
+               return -1;
+       }
+
+       if (tdb_delete(idmap_tdb, key) != 0) {
+               d_fprintf(stderr, "Could not delete key %s\n", argv[1]);
+               return -1;
+       }
+
+       if (tdb_delete(idmap_tdb, data) != 0) {
+               d_fprintf(stderr, "Could not delete key %s\n", data.dptr);
+               return -1;
+       }
+
+       return 0;
+}
+
+
 int net_help_idmap(int argc, const char **argv)
 {
-       d_printf("net idmap dump filename"\
+       d_printf("net idmap dump <tdbfile>"\
                 "\n  Dump current id mapping\n");
 
        d_printf("net idmap restore"\
                 "\n  Restore entries from stdin to current local idmap\n");
 
+       /* Deliberately *not* document net idmap delete */
+
        return -1;
 }
 
@@ -255,6 +316,7 @@ int net_idmap(int argc, const char **argv)
        struct functable func[] = {
                {"dump", net_idmap_dump},
                {"restore", net_idmap_restore},
+               {"delete", net_idmap_delete},
                {"help", net_help_idmap},
                {NULL, NULL}
        };