lib/replace: make sure krb5_cc_default[_name]() is no longer used directly
[metze/samba-autobuild/.git] / source3 / utils / pdbedit.c
index 23c4e71e0d228d21b6e8161fa7511fd45f68df3b..eb6b98239028b89c45551ef1dce99c9ff577dba6 100644 (file)
 */
 
 #include "includes.h"
+#include "lib/cmdline/cmdline.h"
+#include "../librpc/gen_ndr/samr.h"
+#include "../libcli/security/security.h"
+#include "passdb.h"
+#include "cmdline_contexts.h"
+#include "passwd_proto.h"
+#include "lib/util/smb_strtox.h"
+#include "lib/param/param.h"
 
 #define BIT_BACKEND    0x00000004
 #define BIT_VERBOSE    0x00000008
 #define BIT_FIX_INIT    0x04000000
 #define BIT_BADPWRESET 0x08000000
 #define BIT_LOGONHOURS 0x10000000
+#define BIT_KICKOFFTIME        0x20000000
+#define BIT_DESCRIPTION 0x40000000
+#define BIT_PWSETNTHASH 0x80000000
 
 #define MASK_ALWAYS_GOOD       0x0000001F
-#define MASK_USER_GOOD         0x00405FE0
+#define MASK_USER_GOOD         0xE0405FE0
 
-static int get_sid_from_cli_string(DOM_SID *sid, const char *str_sid)
+static int get_sid_from_cli_string(struct dom_sid *sid, const char *str_sid)
 {
        uint32_t rid;
 
@@ -66,8 +77,7 @@ static int get_sid_from_cli_string(DOM_SID *sid, const char *str_sid)
                                        "a complete SID or RID!\n");
                        return -1;
                }
-               sid_copy(sid, get_global_sam_sid());
-               sid_append_rid(sid, rid);
+               sid_compose(sid, get_global_sam_sid(), rid);
        }
 
        return 0;
@@ -102,7 +112,7 @@ static int export_database (struct pdb_methods *in,
        while (u_search->next_entry(u_search, &userentry)) {
                struct samu *user;
                struct samu *account;
-               DOM_SID user_sid;
+               struct dom_sid user_sid;
 
                DEBUG(4, ("Processing account %s\n", userentry.account_name));
 
@@ -170,7 +180,7 @@ static int export_database (struct pdb_methods *in,
 
 static int export_groups (struct pdb_methods *in, struct pdb_methods *out)
 {
-       GROUP_MAP *maps = NULL;
+       GROUP_MAP **maps = NULL;
        size_t i, entries = 0;
        NTSTATUS status;
 
@@ -183,10 +193,10 @@ static int export_groups (struct pdb_methods *in, struct pdb_methods *out)
        }
 
        for (i=0; i<entries; i++) {
-               out->add_group_mapping_entry(out, &(maps[i]));
+               out->add_group_mapping_entry(out, maps[i]);
        }
 
-       SAFE_FREE( maps );
+       TALLOC_FREE(maps);
 
        return 0;
 }
@@ -200,7 +210,7 @@ static int reinit_account_policies (void)
        int i;
 
        for (i=1; decode_account_policy_name(i) != NULL; i++) {
-               uint32 policy_value;
+               uint32_t policy_value;
                if (!account_policy_get_default(i, &policy_value)) {
                        fprintf(stderr, "Can't get default account policy\n");
                        return -1;
@@ -219,12 +229,12 @@ static int reinit_account_policies (void)
  Add all currently available account policy from tdb to one backend
  ********************************************************/
 
-static int export_account_policies (struct pdb_methods *in, struct pdb_methods *out) 
+static int export_account_policies (struct pdb_methods *in, struct pdb_methods *out)
 {
        int i;
 
        for ( i=1; decode_account_policy_name(i) != NULL; i++ ) {
-               uint32 policy_value;
+               uint32_t policy_value;
                NTSTATUS status;
 
                status = in->get_account_policy(in, i, &policy_value);
@@ -260,15 +270,16 @@ static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdst
 
        if (verbosity) {
                char temp[44];
-               const uint8 *hours;
+               const uint8_t *hours;
+               struct dom_sid_buf buf;
 
                printf ("Unix username:        %s\n", pdb_get_username(sam_pwent));
                printf ("NT username:          %s\n", pdb_get_nt_username(sam_pwent));
                printf ("Account Flags:        %s\n", pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent), NEW_PW_FORMAT_SPACE_PADDED_LEN));
                printf ("User SID:             %s\n",
-                       sid_string_tos(pdb_get_user_sid(sam_pwent)));
+                       dom_sid_str_buf(pdb_get_user_sid(sam_pwent), &buf));
                printf ("Primary Group SID:    %s\n",
-                       sid_string_tos(pdb_get_group_sid(sam_pwent)));
+                       dom_sid_str_buf(pdb_get_group_sid(sam_pwent), &buf));
                printf ("Full Name:            %s\n", pdb_get_fullname(sam_pwent));
                printf ("Home Directory:       %s\n", pdb_get_homedir(sam_pwent));
                printf ("HomeDir Drive:        %s\n", pdb_get_dir_drive(sam_pwent));
@@ -312,6 +323,12 @@ static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdst
                hours = pdb_get_hours(sam_pwent);
                pdb_sethexhours(temp, hours);
                printf ("Logon hours         : %s\n", temp);
+               if (smbpwdstyle){
+                       pdb_sethexpwd(temp, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
+                       printf ("LM hash             : %s\n", temp);
+                       pdb_sethexpwd(temp, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
+                       printf ("NT hash             : %s\n", temp);
+               }
 
        } else if (smbpwdstyle) {
                char lm_passwd[33];
@@ -327,7 +344,7 @@ static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdst
                       lm_passwd,
                       nt_passwd,
                       pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent),NEW_PW_FORMAT_SPACE_PADDED_LEN),
-                      (uint32)convert_time_t_to_uint32(pdb_get_pass_last_set_time(sam_pwent)));
+                      (uint32_t)convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sam_pwent)));
        } else {
                uid = nametouid(pdb_get_username(sam_pwent));
                printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid,
@@ -375,7 +392,7 @@ static int print_users_list(bool verbosity, bool smbpwdstyle)
        struct samr_displayentry userentry;
        struct samu *sam_pwent;
        TALLOC_CTX *tosctx;
-       DOM_SID user_sid;
+       struct dom_sid user_sid;
        bool bret;
        int ret;
 
@@ -433,7 +450,7 @@ static int fix_users_list(void)
        struct samr_displayentry userentry;
        struct samu *sam_pwent;
        TALLOC_CTX *tosctx;
-       DOM_SID user_sid;
+       struct dom_sid user_sid;
        NTSTATUS status;
        bool bret;
        int ret;
@@ -493,7 +510,8 @@ static int set_user_info(const char *username, const char *fullname,
                         const char *drive, const char *script,
                         const char *profile, const char *account_control,
                         const char *user_sid, const char *user_domain,
-                        const bool badpw, const bool hours)
+                        const bool badpw, const bool hours,
+                        const char *kickoff_time, const char *str_hex_pwd)
 {
        bool updated_autolock = False, updated_badpw = False;
        struct samu *sam_pwent;
@@ -502,7 +520,7 @@ static int set_user_info(const char *username, const char *fullname,
        uint32_t acb_flags;
        uint32_t not_settable;
        uint32_t new_flags;
-       DOM_SID u_sid;
+       struct dom_sid u_sid;
        bool ret;
 
        sam_pwent = samu_new(NULL);
@@ -521,7 +539,7 @@ static int set_user_info(const char *username, const char *fullname,
                hours_len = pdb_get_hours_len(sam_pwent);
                memset(hours_array, 0xff, hours_len);
 
-               pdb_set_hours(sam_pwent, hours_array, PDB_CHANGED);
+               pdb_set_hours(sam_pwent, hours_array, hours_len, PDB_CHANGED);
        }
 
        if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) {
@@ -578,8 +596,55 @@ static int set_user_info(const char *username, const char *fullname,
                pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED);
        }
 
+       if (kickoff_time) {
+               time_t value = get_time_t_max();
+
+               if (strcmp(kickoff_time, "never") != 0) {
+                       int error = 0;
+                       uint32_t num;
+
+                       num = smb_strtoul(kickoff_time,
+                                         NULL,
+                                         10,
+                                         &error,
+                                         SMB_STR_FULL_STR_CONV);
+                       if (error != 0) {
+                               fprintf(stderr, "Failed to parse kickoff time\n");
+                               return -1;
+                       }
+
+                       value = convert_uint32_t_to_time_t(num);
+               }
+
+               pdb_set_kickoff_time(sam_pwent, value, PDB_CHANGED);
+       }
+       if (str_hex_pwd) {
+               unsigned char  new_nt_p16[NT_HASH_LEN];
+               if(strlen(str_hex_pwd) != (NT_HASH_LEN *2)){
+                       fprintf(stderr, "Invalid hash\n");
+                       return -1;
+               }
+
+               pdb_gethexpwd(str_hex_pwd, new_nt_p16);
+
+               if (!pdb_set_nt_passwd (sam_pwent, new_nt_p16 , PDB_CHANGED)) {
+                       fprintf(stderr, "Failed to set password from nt-hash\n");
+                       return -1;
+               }
+
+               if (!pdb_set_pass_last_set_time (sam_pwent, time(NULL), PDB_CHANGED)){
+                       fprintf(stderr, "Failed to set last password set time\n");
+                       return -1;
+               }
+               if (!pdb_update_history(sam_pwent, new_nt_p16)){
+                       fprintf(stderr, "Failed to update password history\n");
+                       return -1;
+               }
+       }
+
        if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
-               print_user_info(username, True, False);
+
+               print_user_info(username, True, (str_hex_pwd != NULL ));
        } else {
                fprintf (stderr, "Unable to modify entry!\n");
                TALLOC_FREE(sam_pwent);
@@ -598,7 +663,7 @@ static int set_machine_info(const char *machinename,
        uint32_t acb_flags;
        uint32_t not_settable;
        uint32_t new_flags;
-       DOM_SID m_sid;
+       struct dom_sid m_sid;
        char *name;
        int len;
        bool ret;
@@ -631,7 +696,11 @@ static int set_machine_info(const char *machinename,
                return -1;
        }
 
-       strlower_m(name);
+       if (!strlower_m(name)) {
+               fprintf(stderr, "strlower_m %s failed\n", name);
+               TALLOC_FREE(sam_pwent);
+               return -1;
+       }
 
        ret = pdb_getsampwnam(sam_pwent, name);
        if (!ret) {
@@ -689,9 +758,9 @@ static int new_user(const char *username, const char *fullname,
        struct samu *sam_pwent = NULL;
        TALLOC_CTX *tosctx;
        NTSTATUS status;
-       DOM_SID u_sid;
+       struct dom_sid u_sid;
        int flags;
-       int ret;
+       int ret = -1;
 
        tosctx = talloc_tos();
        if (!tosctx) {
@@ -707,7 +776,15 @@ static int new_user(const char *username, const char *fullname,
        }
 
        pwd1 = get_pass( "new password:", stdin_get);
+       if (pwd1 == NULL) {
+               fprintf(stderr, "Failed to read passwords.\n");
+               goto done;
+       }
        pwd2 = get_pass( "retype new password:", stdin_get);
+       if (pwd2 == NULL) {
+               fprintf(stderr, "Failed to read passwords.\n");
+               goto done;
+       }
        ret = strcmp(pwd1, pwd2);
        if (ret != 0) {
                fprintf (stderr, "Passwords do not match!\n");
@@ -782,7 +859,7 @@ static int new_machine(const char *machinename, char *machine_sid)
        struct samu *sam_pwent = NULL;
        TALLOC_CTX *tosctx;
        NTSTATUS status;
-       DOM_SID m_sid;
+       struct dom_sid m_sid;
        char *compatpwd;
        char *name;
        int flags;
@@ -825,7 +902,10 @@ static int new_machine(const char *machinename, char *machine_sid)
                return -1;
        }
 
-       strlower_m(name);
+       if (!strlower_m(name)) {
+               fprintf(stderr, "strlower_m %s failed\n", name);
+               return -1;
+       }
 
        flags = LOCAL_ADD_USER | LOCAL_TRUST_ACCOUNT | LOCAL_SET_PASSWORD;
 
@@ -930,8 +1010,8 @@ static int delete_machine_entry(const char *machinename)
        if (!pdb_getsampwnam(samaccount, name)) {
                fprintf (stderr,
                         "machine %s does not exist in the passdb\n", name);
-               return -1;
                TALLOC_FREE(samaccount);
+               return -1;
        }
 
        if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
@@ -948,7 +1028,7 @@ static int delete_machine_entry(const char *machinename)
  Start here.
 **********************************************************/
 
-int main (int argc, char **argv)
+int main(int argc, const char **argv)
 {
        static int list_users = False;
        static int verbose = False;
@@ -957,7 +1037,7 @@ int main (int argc, char **argv)
        static int add_user = False;
        static int delete_user = False;
        static int modify_user = False;
-       uint32  setparms, checkparms;
+       uint32_t   setparms, checkparms;
        int opt;
        static char *full_name = NULL;
        static char *acct_desc = NULL;
@@ -985,9 +1065,13 @@ int main (int argc, char **argv)
        static char *pwd_time_format = NULL;
        static int pw_from_stdin = False;
        struct pdb_methods *bin, *bout;
+       static char *kickoff_time = NULL;
+       static char *str_hex_pwd = NULL;
        TALLOC_CTX *frame = talloc_stackframe();
+       struct loadparm_context *lp_ctx = NULL;
        NTSTATUS status;
        poptContext pc;
+       bool ok;
        struct poptOption long_options[] = {
                POPT_AUTOHELP
                {"list",        'L', POPT_ARG_NONE, &list_users, 0, "list all users", NULL},
@@ -1021,40 +1105,64 @@ int main (int argc, char **argv)
                {"logon-hours-reset", 'Z', POPT_ARG_NONE, &hours_reset, 0, "reset logon hours", NULL},
                {"time-format", 0, POPT_ARG_STRING, &pwd_time_format, 0, "The time format for time parameters", NULL },
                {"password-from-stdin", 't', POPT_ARG_NONE, &pw_from_stdin, 0, "get password from standard in", NULL},
+               {"kickoff-time", 'K', POPT_ARG_STRING, &kickoff_time, 0, "set the kickoff time", NULL},
+               {"set-nt-hash", 0, POPT_ARG_STRING, &str_hex_pwd, 0, "set password from nt-hash", NULL},
                POPT_COMMON_SAMBA
+               POPT_COMMON_VERSION
                POPT_TABLEEND
        };
 
        bin = bout = NULL;
 
-       load_case_tables();
+       smb_init_locale();
 
-       setup_logging("pdbedit", True);
+       ok = samba_cmdline_init(frame,
+                               SAMBA_CMDLINE_CONFIG_CLIENT,
+                               false /* require_smbconf */);
+       if (!ok) {
+               DBG_ERR("Failed to init cmdline parser!\n");
+               TALLOC_FREE(frame);
+               exit(1);
+       }
+       lp_ctx = samba_cmdline_get_lp_ctx();
 
-       pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
-                           POPT_CONTEXT_KEEP_FIRST);
+       pc = samba_popt_get_context(getprogname(),
+                                   argc,
+                                   argv,
+                                   long_options,
+                                   POPT_CONTEXT_KEEP_FIRST);
+       if (pc == NULL) {
+               DBG_ERR("Failed to setup popt context!\n");
+               TALLOC_FREE(frame);
+               exit(1);
+       }
 
        while((opt = poptGetNextOpt(pc)) != -1) {
                switch (opt) {
                case 'C':
                        account_policy_value_set = True;
                        break;
+               case POPT_ERROR_BADOPT:
+                       fprintf(stderr, "\nInvalid option %s: %s\n\n",
+                               poptBadOption(pc, 0), poptStrerror(opt));
+                       poptPrintUsage(pc, stderr, 0);
+                       exit(1);
                }
        }
 
        poptGetArg(pc); /* Drop argv[0], the program name */
 
-       if (user_name == NULL)
-               user_name = poptGetArg(pc);
-
-       if (!lp_load(get_dyn_CONFIGFILE(),True,False,False,True)) {
-               fprintf(stderr, "Can't load %s - run testparm to debug it\n", get_dyn_CONFIGFILE());
-               exit(1);
+       if (user_name == NULL) {
+               if (poptPeekArg(pc)) {
+                       user_name = talloc_strdup(frame, poptGetArg(pc));
+                       if (user_name == NULL) {
+                               fprintf(stderr, "out of memory\n");
+                               TALLOC_FREE(frame);
+                               exit(1);
+                       }
+               }
        }
 
-       if (!init_names())
-               exit(1);
-
        setparms =      (backend ? BIT_BACKEND : 0) +
                        (verbose ? BIT_VERBOSE : 0) +
                        (spstyle ? BIT_SPSTYLE : 0) +
@@ -1079,13 +1187,17 @@ int main (int argc, char **argv)
                        (backend_in ? BIT_IMPORT : 0) +
                        (backend_out ? BIT_EXPORT : 0) +
                        (badpw_reset ? BIT_BADPWRESET : 0) +
-                       (hours_reset ? BIT_LOGONHOURS : 0);
+                       (hours_reset ? BIT_LOGONHOURS : 0) +
+                       (kickoff_time ? BIT_KICKOFFTIME : 0) +
+                       (str_hex_pwd ? BIT_PWSETNTHASH : 0 ) +
+                       (acct_desc ? BIT_DESCRIPTION : 0);
+
 
        if (setparms & BIT_BACKEND) {
                /* HACK: set the global passdb backend by overwriting globals.
                 * This way we can use regular pdb functions for default
                 * operations that do not involve passdb migrations */
-               lp_set_passdb_backend(backend);
+               lpcfg_set_cmdline(lp_ctx, "passdb backend", backend);
        } else {
                backend = lp_passdb_backend();
        }
@@ -1099,18 +1211,19 @@ int main (int argc, char **argv)
        checkparms = setparms & ~MASK_ALWAYS_GOOD;
 
        if (checkparms & BIT_FIX_INIT) {
+               poptFreeContext(pc);
                return fix_users_list();
        }
 
        /* account policy operations */
        if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) {
-               uint32 value;
-               int field = account_policy_name_to_fieldnum(account_policy);
+               uint32_t value;
+               enum pdb_policy_type field = account_policy_name_to_typenum(account_policy);
                if (field == 0) {
                        const char **names;
                        int count;
                        int i;
-                       account_policy_names_list(&names, &count);
+                       account_policy_names_list(talloc_tos(), &names, &count);
                        fprintf(stderr, "No account policy by that name!\n");
                        if (count !=0) {
                                fprintf(stderr, "Account policy names are:\n");
@@ -1118,7 +1231,7 @@ int main (int argc, char **argv)
                                        d_fprintf(stderr, "%s\n", names[i]);
                                }
                        }
-                       SAFE_FREE(names);
+                       TALLOC_FREE(names);
                        exit(1);
                }
                if (!pdb_get_account_policy(field, &value)) {
@@ -1142,7 +1255,7 @@ int main (int argc, char **argv)
        }
 
        if (reset_account_policies) {
-               if (!reinit_account_policies()) {
+               if (reinit_account_policies()) {
                        exit(1);
                }
 
@@ -1155,6 +1268,8 @@ int main (int argc, char **argv)
             (checkparms & BIT_EXPORT)) &&
            !(checkparms & ~(BIT_IMPORT +BIT_EXPORT +BIT_USER))) {
 
+               poptFreeContext(pc);
+
                if (backend_in) {
                        status = make_pdb_method_name(&bin, backend_in);
                } else {
@@ -1212,9 +1327,11 @@ int main (int argc, char **argv)
        /* list users operations */
        if (checkparms & BIT_LIST) {
                if (!(checkparms & ~BIT_LIST)) {
+                       poptFreeContext(pc);
                        return print_users_list(verbose, spstyle);
                }
                if (!(checkparms & ~(BIT_USER + BIT_LIST))) {
+                       poptFreeContext(pc);
                        return print_user_info(user_name, verbose, spstyle);
                }
        }
@@ -1239,12 +1356,14 @@ int main (int argc, char **argv)
                /* check use of -u option */
                if (!(checkparms & BIT_USER)) {
                        fprintf (stderr, "Username not specified! (use -u option)\n");
+                       poptFreeContext(pc);
                        return -1;
                }
 
                /* account creation operations */
                if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE))) {
-                       if (checkparms & BIT_MACHINE) {
+                       poptFreeContext(pc);
+                       if (checkparms & BIT_MACHINE) {
                                return new_machine(user_name, machine_sid);
                        } else {
                                return new_user(user_name, full_name,
@@ -1256,7 +1375,8 @@ int main (int argc, char **argv)
 
                /* account deletion operations */
                if (!(checkparms & ~(BIT_DELETE + BIT_USER + BIT_MACHINE))) {
-                       if (checkparms & BIT_MACHINE) {
+                       poptFreeContext(pc);
+                       if (checkparms & BIT_MACHINE) {
                                return delete_machine_entry(user_name);
                        } else {
                                return delete_user_entry(user_name);
@@ -1265,6 +1385,7 @@ int main (int argc, char **argv)
 
                /* account modification operations */
                if (!(checkparms & ~(BIT_MODIFY + BIT_USER + BIT_MACHINE))) {
+                       poptFreeContext(pc);
                        if (checkparms & BIT_MACHINE) {
                                return set_machine_info(user_name,
                                                        account_control,
@@ -1275,7 +1396,8 @@ int main (int argc, char **argv)
                                                     home_drive, logon_script,
                                                     profile_path, account_control,
                                                     user_sid, user_domain,
-                                                    badpw_reset, hours_reset);
+                                                    badpw_reset, hours_reset,
+                                                    kickoff_time, str_hex_pwd);
                        }
                }
        }
@@ -1285,6 +1407,8 @@ int main (int argc, char **argv)
        }
        poptPrintHelp(pc, stderr, 0);
 
+       gfree_all();
+       poptFreeContext(pc);
        TALLOC_FREE(frame);
        return 1;
 }