LCOV - code coverage report
Current view: top level - source3/utils - pdbedit.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 212 680 31.2 %
Date: 2024-02-28 12:06:22 Functions: 6 16 37.5 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    passdb editing frontend
       4             : 
       5             :    Copyright (C) Simo Sorce      2000-2009
       6             :    Copyright (C) Andrew Bartlett 2001
       7             :    Copyright (C) Jelmer Vernooij 2002
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "lib/cmdline/cmdline.h"
      25             : #include "../librpc/gen_ndr/samr.h"
      26             : #include "../libcli/security/security.h"
      27             : #include "passdb.h"
      28             : #include "cmdline_contexts.h"
      29             : #include "passwd_proto.h"
      30             : #include "lib/util/smb_strtox.h"
      31             : #include "lib/param/param.h"
      32             : 
      33             : #define BIT_BACKEND     0x00000004
      34             : #define BIT_VERBOSE     0x00000008
      35             : #define BIT_SPSTYLE     0x00000010
      36             : #define BIT_CAN_CHANGE  0x00000020
      37             : #define BIT_MUST_CHANGE 0x00000040
      38             : #define BIT_USERSIDS    0x00000080
      39             : #define BIT_FULLNAME    0x00000100
      40             : #define BIT_HOMEDIR     0x00000200
      41             : #define BIT_HDIRDRIVE   0x00000400
      42             : #define BIT_LOGSCRIPT   0x00000800
      43             : #define BIT_PROFILE     0x00001000
      44             : #define BIT_MACHINE     0x00002000
      45             : #define BIT_USERDOMAIN  0x00004000
      46             : #define BIT_USER        0x00008000
      47             : #define BIT_LIST        0x00010000
      48             : #define BIT_MODIFY      0x00020000
      49             : #define BIT_CREATE      0x00040000
      50             : #define BIT_DELETE      0x00080000
      51             : #define BIT_ACCPOLICY   0x00100000
      52             : #define BIT_ACCPOLVAL   0x00200000
      53             : #define BIT_ACCTCTRL    0x00400000
      54             : #define BIT_RESERV_7    0x00800000
      55             : #define BIT_IMPORT      0x01000000
      56             : #define BIT_EXPORT      0x02000000
      57             : #define BIT_FIX_INIT    0x04000000
      58             : #define BIT_BADPWRESET  0x08000000
      59             : #define BIT_LOGONHOURS  0x10000000
      60             : #define BIT_KICKOFFTIME 0x20000000
      61             : #define BIT_DESCRIPTION 0x40000000
      62             : #define BIT_PWSETNTHASH 0x80000000
      63             : 
      64             : #define MASK_ALWAYS_GOOD        0x0000001F
      65             : #define MASK_USER_GOOD          0xE0405FE0
      66             : 
      67           0 : static int get_sid_from_cli_string(struct dom_sid *sid, const char *str_sid)
      68             : {
      69             :         uint32_t rid;
      70             : 
      71           0 :         if (!string_to_sid(sid, str_sid)) {
      72             :                 /* not a complete sid, may be a RID,
      73             :                  * try building a SID */
      74             : 
      75           0 :                 if (sscanf(str_sid, "%u", &rid) != 1) {
      76           0 :                         fprintf(stderr, "Error passed string is not "
      77             :                                         "a complete SID or RID!\n");
      78           0 :                         return -1;
      79             :                 }
      80           0 :                 sid_compose(sid, get_global_sam_sid(), rid);
      81             :         }
      82             : 
      83           0 :         return 0;
      84             : }
      85             : 
      86             : /*********************************************************
      87             :  Add all currently available users to another db
      88             :  ********************************************************/
      89             : 
      90           0 : static int export_database (struct pdb_methods *in,
      91             :                             struct pdb_methods *out,
      92             :                             const char *username)
      93             : {
      94             :         NTSTATUS status;
      95             :         struct pdb_search *u_search;
      96             :         struct samr_displayentry userentry;
      97             : 
      98           0 :         DEBUG(3, ("export_database: username=\"%s\"\n", username ? username : "(NULL)"));
      99             : 
     100           0 :         u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH);
     101           0 :         if (u_search == NULL) {
     102           0 :                 DEBUG(0, ("pdb_search_init failed\n"));
     103           0 :                 return 1;
     104             :         }
     105             : 
     106           0 :         if (!in->search_users(in, u_search, 0)) {
     107           0 :                 DEBUG(0, ("Could not start searching users\n"));
     108           0 :                 TALLOC_FREE(u_search);
     109           0 :                 return 1;
     110             :         }
     111             : 
     112           0 :         while (u_search->next_entry(u_search, &userentry)) {
     113             :                 struct samu *user;
     114             :                 struct samu *account;
     115             :                 struct dom_sid user_sid;
     116             : 
     117           0 :                 DEBUG(4, ("Processing account %s\n", userentry.account_name));
     118             : 
     119           0 :                 if ((username != NULL)
     120           0 :                     && (strcmp(username, userentry.account_name) != 0)) {
     121             :                         /*
     122             :                          * ignore unwanted users
     123             :                          */
     124           0 :                         continue;
     125             :                 }
     126             : 
     127           0 :                 user = samu_new(talloc_tos());
     128           0 :                 if (user == NULL) {
     129           0 :                         DEBUG(0, ("talloc failed\n"));
     130           0 :                         break;
     131             :                 }
     132             : 
     133           0 :                 sid_compose(&user_sid, get_global_sam_sid(), userentry.rid);
     134             : 
     135           0 :                 status = in->getsampwsid(in, user, &user_sid);
     136             : 
     137           0 :                 if (!NT_STATUS_IS_OK(status)) {
     138           0 :                         DEBUG(2, ("getsampwsid failed: %s\n",
     139             :                                   nt_errstr(status)));
     140           0 :                         TALLOC_FREE(user);
     141           0 :                         continue;
     142             :                 }
     143             : 
     144           0 :                 account = samu_new(NULL);
     145           0 :                 if (account == NULL) {
     146           0 :                         fprintf(stderr, "export_database: Memory allocation "
     147             :                                 "failure!\n");
     148           0 :                         TALLOC_FREE( user );
     149           0 :                         TALLOC_FREE(u_search);
     150           0 :                         return 1;
     151             :                 }
     152             : 
     153           0 :                 printf("Importing account for %s...", user->username);
     154           0 :                 status = out->getsampwnam(out, account, user->username);
     155             : 
     156           0 :                 if (NT_STATUS_IS_OK(status)) {
     157           0 :                         status = out->update_sam_account( out, user );
     158             :                 } else {
     159           0 :                         status = out->add_sam_account(out, user);
     160             :                 }
     161             : 
     162           0 :                 if ( NT_STATUS_IS_OK(status) ) {
     163           0 :                         printf( "ok\n");
     164             :                 } else {
     165           0 :                         printf( "failed\n");
     166             :                 }
     167             : 
     168           0 :                 TALLOC_FREE( account );
     169           0 :                 TALLOC_FREE( user );
     170             :         }
     171             : 
     172           0 :         TALLOC_FREE(u_search);
     173             : 
     174           0 :         return 0;
     175             : }
     176             : 
     177             : /*********************************************************
     178             :  Add all currently available group mappings to another db
     179             :  ********************************************************/
     180             : 
     181           0 : static int export_groups (struct pdb_methods *in, struct pdb_methods *out)
     182             : {
     183           0 :         GROUP_MAP **maps = NULL;
     184           0 :         size_t i, entries = 0;
     185             :         NTSTATUS status;
     186             : 
     187           0 :         status = in->enum_group_mapping(in, get_global_sam_sid(),
     188             :                         SID_NAME_DOM_GRP, &maps, &entries, False);
     189             : 
     190           0 :         if ( NT_STATUS_IS_ERR(status) ) {
     191           0 :                 fprintf(stderr, "Unable to enumerate group map entries.\n");
     192           0 :                 return 1;
     193             :         }
     194             : 
     195           0 :         for (i=0; i<entries; i++) {
     196           0 :                 out->add_group_mapping_entry(out, maps[i]);
     197             :         }
     198             : 
     199           0 :         TALLOC_FREE(maps);
     200             : 
     201           0 :         return 0;
     202             : }
     203             : 
     204             : /*********************************************************
     205             :  Reset account policies to their default values and remove marker
     206             :  ********************************************************/
     207             : 
     208           0 : static int reinit_account_policies (void)
     209             : {
     210             :         int i;
     211             : 
     212           0 :         for (i=1; decode_account_policy_name(i) != NULL; i++) {
     213             :                 uint32_t policy_value;
     214           0 :                 if (!account_policy_get_default(i, &policy_value)) {
     215           0 :                         fprintf(stderr, "Can't get default account policy\n");
     216           0 :                         return -1;
     217             :                 }
     218           0 :                 if (!account_policy_set(i, policy_value)) {
     219           0 :                         fprintf(stderr, "Can't set account policy in tdb\n");
     220           0 :                         return -1;
     221             :                 }
     222             :         }
     223             : 
     224           0 :         return 0;
     225             : }
     226             : 
     227             : 
     228             : /*********************************************************
     229             :  Add all currently available account policy from tdb to one backend
     230             :  ********************************************************/
     231             : 
     232           0 : static int export_account_policies (struct pdb_methods *in, struct pdb_methods *out)
     233             : {
     234             :         int i;
     235             : 
     236           0 :         for ( i=1; decode_account_policy_name(i) != NULL; i++ ) {
     237             :                 uint32_t policy_value;
     238             :                 NTSTATUS status;
     239             : 
     240           0 :                 status = in->get_account_policy(in, i, &policy_value);
     241             : 
     242           0 :                 if ( NT_STATUS_IS_ERR(status) ) {
     243           0 :                         fprintf(stderr, "Unable to get account policy from %s\n", in->name);
     244           0 :                         return -1;
     245             :                 }
     246             : 
     247           0 :                 status = out->set_account_policy(out, i, policy_value);
     248             : 
     249           0 :                 if ( NT_STATUS_IS_ERR(status) ) {
     250           0 :                         fprintf(stderr, "Unable to migrate account policy to %s\n", out->name);
     251           0 :                         return -1;
     252             :                 }
     253             :         }
     254             : 
     255           0 :         return 0;
     256             : }
     257             : 
     258             : 
     259             : /*********************************************************
     260             :  Print info from sam structure
     261             : **********************************************************/
     262             : 
     263           9 : static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdstyle)
     264             : {
     265             :         uid_t uid;
     266             :         time_t tmp;
     267             : 
     268             :         /* TODO: check if entry is a user or a workstation */
     269           9 :         if (!sam_pwent) return -1;
     270             : 
     271           9 :         if (verbosity) {
     272             :                 char temp[44];
     273             :                 const uint8_t *hours;
     274             :                 struct dom_sid_buf buf;
     275             : 
     276           9 :                 printf ("Unix username:        %s\n", pdb_get_username(sam_pwent));
     277           9 :                 printf ("NT username:          %s\n", pdb_get_nt_username(sam_pwent));
     278           9 :                 printf ("Account Flags:        %s\n", pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent), NEW_PW_FORMAT_SPACE_PADDED_LEN));
     279           9 :                 printf ("User SID:             %s\n",
     280             :                         dom_sid_str_buf(pdb_get_user_sid(sam_pwent), &buf));
     281           9 :                 printf ("Primary Group SID:    %s\n",
     282             :                         dom_sid_str_buf(pdb_get_group_sid(sam_pwent), &buf));
     283           9 :                 printf ("Full Name:            %s\n", pdb_get_fullname(sam_pwent));
     284           9 :                 printf ("Home Directory:       %s\n", pdb_get_homedir(sam_pwent));
     285           9 :                 printf ("HomeDir Drive:        %s\n", pdb_get_dir_drive(sam_pwent));
     286           9 :                 printf ("Logon Script:         %s\n", pdb_get_logon_script(sam_pwent));
     287           9 :                 printf ("Profile Path:         %s\n", pdb_get_profile_path(sam_pwent));
     288           9 :                 printf ("Domain:               %s\n", pdb_get_domain(sam_pwent));
     289           9 :                 printf ("Account desc:         %s\n", pdb_get_acct_desc(sam_pwent));
     290           9 :                 printf ("Workstations:         %s\n", pdb_get_workstations(sam_pwent));
     291           9 :                 printf ("Munged dial:          %s\n", pdb_get_munged_dial(sam_pwent));
     292             : 
     293           9 :                 tmp = pdb_get_logon_time(sam_pwent);
     294          11 :                 printf ("Logon time:           %s\n",
     295           2 :                                 tmp ? http_timestring(talloc_tos(), tmp) : "0");
     296             : 
     297           9 :                 tmp = pdb_get_logoff_time(sam_pwent);
     298          15 :                 printf ("Logoff time:          %s\n",
     299           6 :                                 tmp ? http_timestring(talloc_tos(), tmp) : "0");
     300             : 
     301           9 :                 tmp = pdb_get_kickoff_time(sam_pwent);
     302          18 :                 printf ("Kickoff time:         %s\n",
     303           9 :                                 tmp ? http_timestring(talloc_tos(), tmp) : "0");
     304             : 
     305           9 :                 tmp = pdb_get_pass_last_set_time(sam_pwent);
     306          18 :                 printf ("Password last set:    %s\n",
     307           9 :                                 tmp ? http_timestring(talloc_tos(), tmp) : "0");
     308             : 
     309           9 :                 tmp = pdb_get_pass_can_change_time(sam_pwent);
     310          18 :                 printf ("Password can change:  %s\n",
     311           9 :                                 tmp ? http_timestring(talloc_tos(), tmp) : "0");
     312             : 
     313           9 :                 tmp = pdb_get_pass_must_change_time(sam_pwent);
     314          18 :                 printf ("Password must change: %s\n",
     315           9 :                                 tmp ? http_timestring(talloc_tos(), tmp) : "0");
     316             : 
     317           9 :                 tmp = pdb_get_bad_password_time(sam_pwent);
     318           9 :                 printf ("Last bad password   : %s\n",
     319           0 :                                 tmp ? http_timestring(talloc_tos(), tmp) : "0");
     320           9 :                 printf ("Bad password count  : %d\n",
     321           9 :                         pdb_get_bad_password_count(sam_pwent));
     322             : 
     323           9 :                 hours = pdb_get_hours(sam_pwent);
     324           9 :                 pdb_sethexhours(temp, hours);
     325           9 :                 printf ("Logon hours         : %s\n", temp);
     326           9 :                 if (smbpwdstyle){
     327           3 :                         pdb_sethexpwd(temp, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
     328           3 :                         printf ("LM hash             : %s\n", temp);
     329           3 :                         pdb_sethexpwd(temp, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
     330           3 :                         printf ("NT hash             : %s\n", temp);
     331             :                 }
     332             : 
     333           0 :         } else if (smbpwdstyle) {
     334             :                 char lm_passwd[33];
     335             :                 char nt_passwd[33];
     336             : 
     337           0 :                 uid = nametouid(pdb_get_username(sam_pwent));
     338           0 :                 pdb_sethexpwd(lm_passwd, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
     339           0 :                 pdb_sethexpwd(nt_passwd, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
     340             : 
     341           0 :                 printf("%s:%lu:%s:%s:%s:LCT-%08X:\n",
     342             :                        pdb_get_username(sam_pwent),
     343             :                        (unsigned long)uid,
     344             :                        lm_passwd,
     345             :                        nt_passwd,
     346             :                        pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent),NEW_PW_FORMAT_SPACE_PADDED_LEN),
     347           0 :                        (uint32_t)convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sam_pwent)));
     348             :         } else {
     349           0 :                 uid = nametouid(pdb_get_username(sam_pwent));
     350           0 :                 printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid,
     351             :                         pdb_get_fullname(sam_pwent));
     352             :         }
     353             : 
     354           9 :         return 0;
     355             : }
     356             : 
     357             : /*********************************************************
     358             :  Get an Print User Info
     359             : **********************************************************/
     360             : 
     361           9 : static int print_user_info(const char *username,
     362             :                            bool verbosity, bool smbpwdstyle)
     363             : {
     364           9 :         struct samu *sam_pwent = NULL;
     365             :         bool bret;
     366             :         int ret;
     367             : 
     368           9 :         sam_pwent = samu_new(NULL);
     369           9 :         if (!sam_pwent) {
     370           0 :                 return -1;
     371             :         }
     372             : 
     373           9 :         bret = pdb_getsampwnam(sam_pwent, username);
     374           9 :         if (!bret) {
     375           0 :                 fprintf (stderr, "Username not found!\n");
     376           0 :                 TALLOC_FREE(sam_pwent);
     377           0 :                 return -1;
     378             :         }
     379             : 
     380           9 :         ret = print_sam_info(sam_pwent, verbosity, smbpwdstyle);
     381             : 
     382           9 :         TALLOC_FREE(sam_pwent);
     383           9 :         return ret;
     384             : }
     385             : 
     386             : /*********************************************************
     387             :  List Users
     388             : **********************************************************/
     389           0 : static int print_users_list(bool verbosity, bool smbpwdstyle)
     390             : {
     391             :         struct pdb_search *u_search;
     392             :         struct samr_displayentry userentry;
     393             :         struct samu *sam_pwent;
     394             :         TALLOC_CTX *tosctx;
     395             :         struct dom_sid user_sid;
     396             :         bool bret;
     397             :         int ret;
     398             : 
     399           0 :         tosctx = talloc_tos();
     400           0 :         if (!tosctx) {
     401           0 :                 DEBUG(0, ("talloc failed\n"));
     402           0 :                 return 1;
     403             :         }
     404             : 
     405           0 :         u_search = pdb_search_users(tosctx, 0);
     406           0 :         if (!u_search) {
     407           0 :                 DEBUG(0, ("User Search failed!\n"));
     408           0 :                 ret = 1;
     409           0 :                 goto done;
     410             :         }
     411             : 
     412           0 :         while (u_search->next_entry(u_search, &userentry)) {
     413             : 
     414           0 :                 sam_pwent = samu_new(tosctx);
     415           0 :                 if (sam_pwent == NULL) {
     416           0 :                         DEBUG(0, ("talloc failed\n"));
     417           0 :                         ret = 1;
     418           0 :                         goto done;
     419             :                 }
     420             : 
     421           0 :                 sid_compose(&user_sid, get_global_sam_sid(), userentry.rid);
     422             : 
     423           0 :                 bret = pdb_getsampwsid(sam_pwent, &user_sid);
     424           0 :                 if (!bret) {
     425           0 :                         DEBUG(2, ("getsampwsid failed\n"));
     426           0 :                         TALLOC_FREE(sam_pwent);
     427           0 :                         continue;
     428             :                 }
     429             : 
     430           0 :                 if (verbosity) {
     431           0 :                         printf ("---------------\n");
     432             :                 }
     433           0 :                 print_sam_info(sam_pwent, verbosity, smbpwdstyle);
     434           0 :                 TALLOC_FREE(sam_pwent);
     435             :         }
     436             : 
     437           0 :         ret = 0;
     438             : 
     439           0 : done:
     440           0 :         TALLOC_FREE(tosctx);
     441           0 :         return ret;
     442             : }
     443             : 
     444             : /*********************************************************
     445             :  Fix a list of Users for uninitialised passwords
     446             : **********************************************************/
     447           0 : static int fix_users_list(void)
     448             : {
     449             :         struct pdb_search *u_search;
     450             :         struct samr_displayentry userentry;
     451             :         struct samu *sam_pwent;
     452             :         TALLOC_CTX *tosctx;
     453             :         struct dom_sid user_sid;
     454             :         NTSTATUS status;
     455             :         bool bret;
     456             :         int ret;
     457             : 
     458           0 :         tosctx = talloc_tos();
     459           0 :         if (!tosctx) {
     460           0 :                 fprintf(stderr, "Out of memory!\n");
     461           0 :                 return 1;
     462             :         }
     463             : 
     464           0 :         u_search = pdb_search_users(tosctx, 0);
     465           0 :         if (!u_search) {
     466           0 :                 fprintf(stderr, "User Search failed!\n");
     467           0 :                 ret = 1;
     468           0 :                 goto done;
     469             :         }
     470             : 
     471           0 :         while (u_search->next_entry(u_search, &userentry)) {
     472             : 
     473           0 :                 sam_pwent = samu_new(tosctx);
     474           0 :                 if (sam_pwent == NULL) {
     475           0 :                         fprintf(stderr, "Out of memory!\n");
     476           0 :                         ret = 1;
     477           0 :                         goto done;
     478             :                 }
     479             : 
     480           0 :                 sid_compose(&user_sid, get_global_sam_sid(), userentry.rid);
     481             : 
     482           0 :                 bret = pdb_getsampwsid(sam_pwent, &user_sid);
     483           0 :                 if (!bret) {
     484           0 :                         DEBUG(2, ("getsampwsid failed\n"));
     485           0 :                         TALLOC_FREE(sam_pwent);
     486           0 :                         continue;
     487             :                 }
     488             : 
     489           0 :                 status = pdb_update_sam_account(sam_pwent);
     490           0 :                 if (!NT_STATUS_IS_OK(status)) {
     491           0 :                         printf("Update of user %s failed!\n",
     492             :                                pdb_get_username(sam_pwent));
     493             :                 }
     494           0 :                 TALLOC_FREE(sam_pwent);
     495             :         }
     496             : 
     497           0 :         ret = 0;
     498             : 
     499           0 : done:
     500           0 :         TALLOC_FREE(tosctx);
     501           0 :         return ret;
     502             : }
     503             : 
     504             : /*********************************************************
     505             :  Set User Info
     506             : **********************************************************/
     507             : 
     508           6 : static int set_user_info(const char *username, const char *fullname,
     509             :                          const char *homedir, const char *acct_desc,
     510             :                          const char *drive, const char *script,
     511             :                          const char *profile, const char *account_control,
     512             :                          const char *user_sid, const char *user_domain,
     513             :                          const bool badpw, const bool hours,
     514             :                          const char *kickoff_time, const char *str_hex_pwd)
     515             : {
     516           6 :         bool updated_autolock = False, updated_badpw = False;
     517             :         struct samu *sam_pwent;
     518             :         uint8_t hours_array[MAX_HOURS_LEN];
     519             :         uint32_t hours_len;
     520             :         uint32_t acb_flags;
     521             :         uint32_t not_settable;
     522             :         uint32_t new_flags;
     523             :         struct dom_sid u_sid;
     524             :         bool ret;
     525             : 
     526           6 :         sam_pwent = samu_new(NULL);
     527           6 :         if (!sam_pwent) {
     528           0 :                 return 1;
     529             :         }
     530             : 
     531           6 :         ret = pdb_getsampwnam(sam_pwent, username);
     532           6 :         if (!ret) {
     533           0 :                 fprintf (stderr, "Username not found!\n");
     534           0 :                 TALLOC_FREE(sam_pwent);
     535           0 :                 return -1;
     536             :         }
     537             : 
     538           6 :         if (hours) {
     539           0 :                 hours_len = pdb_get_hours_len(sam_pwent);
     540           0 :                 memset(hours_array, 0xff, hours_len);
     541             : 
     542           0 :                 pdb_set_hours(sam_pwent, hours_array, hours_len, PDB_CHANGED);
     543             :         }
     544             : 
     545           6 :         if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) {
     546           0 :                 DEBUG(2,("pdb_update_autolock_flag failed.\n"));
     547             :         }
     548             : 
     549           6 :         if (!pdb_update_bad_password_count(sam_pwent, &updated_badpw)) {
     550           0 :                 DEBUG(2,("pdb_update_bad_password_count failed.\n"));
     551             :         }
     552             : 
     553           6 :         if (fullname)
     554           0 :                 pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
     555           6 :         if (acct_desc)
     556           0 :                 pdb_set_acct_desc(sam_pwent, acct_desc, PDB_CHANGED);
     557           6 :         if (homedir)
     558           0 :                 pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
     559           6 :         if (drive)
     560           3 :                 pdb_set_dir_drive(sam_pwent,drive, PDB_CHANGED);
     561           6 :         if (script)
     562           0 :                 pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
     563           6 :         if (profile)
     564           0 :                 pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED);
     565           6 :         if (user_domain)
     566           0 :                 pdb_set_domain(sam_pwent, user_domain, PDB_CHANGED);
     567             : 
     568           6 :         if (account_control) {
     569           0 :                 not_settable = ~(ACB_DISABLED | ACB_HOMDIRREQ |
     570             :                                  ACB_PWNOTREQ | ACB_PWNOEXP | ACB_AUTOLOCK);
     571             : 
     572           0 :                 new_flags = pdb_decode_acct_ctrl(account_control);
     573             : 
     574           0 :                 if (new_flags & not_settable) {
     575           0 :                         fprintf(stderr, "Can only set [NDHLX] flags\n");
     576           0 :                         TALLOC_FREE(sam_pwent);
     577           0 :                         return -1;
     578             :                 }
     579             : 
     580           0 :                 acb_flags = pdb_get_acct_ctrl(sam_pwent);
     581             : 
     582           0 :                 pdb_set_acct_ctrl(sam_pwent,
     583           0 :                                   (acb_flags & not_settable) | new_flags,
     584             :                                   PDB_CHANGED);
     585             :         }
     586           6 :         if (user_sid) {
     587           0 :                 if (get_sid_from_cli_string(&u_sid, user_sid)) {
     588           0 :                         fprintf(stderr, "Failed to parse SID\n");
     589           0 :                         return -1;
     590             :                 }
     591           0 :                 pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED);
     592             :         }
     593             : 
     594           6 :         if (badpw) {
     595           0 :                 pdb_set_bad_password_count(sam_pwent, 0, PDB_CHANGED);
     596           0 :                 pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED);
     597             :         }
     598             : 
     599           6 :         if (kickoff_time) {
     600           0 :                 time_t value = get_time_t_max();
     601             : 
     602           0 :                 if (strcmp(kickoff_time, "never") != 0) {
     603           0 :                         int error = 0;
     604             :                         uint32_t num;
     605             : 
     606           0 :                         num = smb_strtoul(kickoff_time,
     607             :                                           NULL,
     608             :                                           10,
     609             :                                           &error,
     610             :                                           SMB_STR_FULL_STR_CONV);
     611           0 :                         if (error != 0) {
     612           0 :                                 fprintf(stderr, "Failed to parse kickoff time\n");
     613           0 :                                 return -1;
     614             :                         }
     615             : 
     616           0 :                         value = convert_uint32_t_to_time_t(num);
     617             :                 }
     618             : 
     619           0 :                 pdb_set_kickoff_time(sam_pwent, value, PDB_CHANGED);
     620             :         }
     621           6 :         if (str_hex_pwd) {
     622             :                 unsigned char  new_nt_p16[NT_HASH_LEN];
     623           3 :                 if(strlen(str_hex_pwd) != (NT_HASH_LEN *2)){
     624           0 :                         fprintf(stderr, "Invalid hash\n");
     625           0 :                         return -1;
     626             :                 }
     627             : 
     628           3 :                 pdb_gethexpwd(str_hex_pwd, new_nt_p16);
     629             : 
     630           3 :                 if (!pdb_set_nt_passwd (sam_pwent, new_nt_p16 , PDB_CHANGED)) {
     631           0 :                         fprintf(stderr, "Failed to set password from nt-hash\n");
     632           0 :                         return -1;
     633             :                 }
     634             : 
     635           3 :                 if (!pdb_set_pass_last_set_time (sam_pwent, time(NULL), PDB_CHANGED)){
     636           0 :                         fprintf(stderr, "Failed to set last password set time\n");
     637           0 :                         return -1;
     638             :                 }
     639           3 :                 if (!pdb_update_history(sam_pwent, new_nt_p16)){
     640           0 :                         fprintf(stderr, "Failed to update password history\n");
     641           0 :                         return -1;
     642             :                 }
     643             :         }
     644             : 
     645           6 :         if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
     646             : 
     647           6 :                 print_user_info(username, True, (str_hex_pwd != NULL ));
     648             :         } else {
     649           0 :                 fprintf (stderr, "Unable to modify entry!\n");
     650           0 :                 TALLOC_FREE(sam_pwent);
     651           0 :                 return -1;
     652             :         }
     653           6 :         TALLOC_FREE(sam_pwent);
     654           6 :         return 0;
     655             : }
     656             : 
     657           0 : static int set_machine_info(const char *machinename,
     658             :                             const char *account_control,
     659             :                             const char *machine_sid)
     660             : {
     661           0 :         struct samu *sam_pwent = NULL;
     662             :         TALLOC_CTX *tosctx;
     663             :         uint32_t acb_flags;
     664             :         uint32_t not_settable;
     665             :         uint32_t new_flags;
     666             :         struct dom_sid m_sid;
     667             :         char *name;
     668             :         int len;
     669             :         bool ret;
     670             : 
     671           0 :         len = strlen(machinename);
     672           0 :         if (len == 0) {
     673           0 :                 fprintf(stderr, "No machine name given\n");
     674           0 :                 return -1;
     675             :         }
     676             : 
     677           0 :         tosctx = talloc_tos();
     678           0 :         if (!tosctx) {
     679           0 :                 fprintf(stderr, "Out of memory!\n");
     680           0 :                 return -1;
     681             :         }
     682             : 
     683           0 :         sam_pwent = samu_new(tosctx);
     684           0 :         if (!sam_pwent) {
     685           0 :                 return 1;
     686             :         }
     687             : 
     688           0 :         if (machinename[len-1] == '$') {
     689           0 :                 name = talloc_strdup(sam_pwent, machinename);
     690             :         } else {
     691           0 :                 name = talloc_asprintf(sam_pwent, "%s$", machinename);
     692             :         }
     693           0 :         if (!name) {
     694           0 :                 fprintf(stderr, "Out of memory!\n");
     695           0 :                 TALLOC_FREE(sam_pwent);
     696           0 :                 return -1;
     697             :         }
     698             : 
     699           0 :         if (!strlower_m(name)) {
     700           0 :                 fprintf(stderr, "strlower_m %s failed\n", name);
     701           0 :                 TALLOC_FREE(sam_pwent);
     702           0 :                 return -1;
     703             :         }
     704             : 
     705           0 :         ret = pdb_getsampwnam(sam_pwent, name);
     706           0 :         if (!ret) {
     707           0 :                 fprintf (stderr, "Username not found!\n");
     708           0 :                 TALLOC_FREE(sam_pwent);
     709           0 :                 return -1;
     710             :         }
     711             : 
     712           0 :         if (account_control) {
     713           0 :                 not_settable = ~(ACB_DISABLED);
     714             : 
     715           0 :                 new_flags = pdb_decode_acct_ctrl(account_control);
     716             : 
     717           0 :                 if (new_flags & not_settable) {
     718           0 :                         fprintf(stderr, "Can only set [D] flags\n");
     719           0 :                         TALLOC_FREE(sam_pwent);
     720           0 :                         return -1;
     721             :                 }
     722             : 
     723           0 :                 acb_flags = pdb_get_acct_ctrl(sam_pwent);
     724             : 
     725           0 :                 pdb_set_acct_ctrl(sam_pwent,
     726           0 :                                   (acb_flags & not_settable) | new_flags,
     727             :                                   PDB_CHANGED);
     728             :         }
     729           0 :         if (machine_sid) {
     730           0 :                 if (get_sid_from_cli_string(&m_sid, machine_sid)) {
     731           0 :                         fprintf(stderr, "Failed to parse SID\n");
     732           0 :                         return -1;
     733             :                 }
     734           0 :                 pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED);
     735             :         }
     736             : 
     737           0 :         if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
     738           0 :                 print_user_info(name, True, False);
     739             :         } else {
     740           0 :                 fprintf (stderr, "Unable to modify entry!\n");
     741           0 :                 TALLOC_FREE(sam_pwent);
     742           0 :                 return -1;
     743             :         }
     744           0 :         TALLOC_FREE(sam_pwent);
     745           0 :         return 0;
     746             : }
     747             : 
     748             : /*********************************************************
     749             :  Add New User
     750             : **********************************************************/
     751           3 : static int new_user(const char *username, const char *fullname,
     752             :                     const char *homedir, const char *drive,
     753             :                     const char *script, const char *profile,
     754             :                     char *user_sid, bool stdin_get)
     755             : {
     756           3 :         char *pwd1 = NULL, *pwd2 = NULL;
     757           3 :         char *err = NULL, *msg = NULL;
     758           3 :         struct samu *sam_pwent = NULL;
     759             :         TALLOC_CTX *tosctx;
     760             :         NTSTATUS status;
     761             :         struct dom_sid u_sid;
     762             :         int flags;
     763           3 :         int ret = -1;
     764             : 
     765           3 :         tosctx = talloc_tos();
     766           3 :         if (!tosctx) {
     767           0 :                 fprintf(stderr, "Out of memory!\n");
     768           0 :                 return -1;
     769             :         }
     770             : 
     771           3 :         if (user_sid) {
     772           0 :                 if (get_sid_from_cli_string(&u_sid, user_sid)) {
     773           0 :                         fprintf(stderr, "Failed to parse SID\n");
     774           0 :                         return -1;
     775             :                 }
     776             :         }
     777             : 
     778           3 :         pwd1 = get_pass( "new password:", stdin_get);
     779           3 :         if (pwd1 == NULL) {
     780           0 :                 fprintf(stderr, "Failed to read passwords.\n");
     781           0 :                 goto done;
     782             :         }
     783           3 :         pwd2 = get_pass( "retype new password:", stdin_get);
     784           3 :         if (pwd2 == NULL) {
     785           0 :                 fprintf(stderr, "Failed to read passwords.\n");
     786           0 :                 goto done;
     787             :         }
     788           3 :         ret = strcmp(pwd1, pwd2);
     789           3 :         if (ret != 0) {
     790           0 :                 fprintf (stderr, "Passwords do not match!\n");
     791           0 :                 goto done;
     792             :         }
     793             : 
     794           3 :         flags = LOCAL_ADD_USER | LOCAL_SET_PASSWORD;
     795             : 
     796           3 :         status = local_password_change(username, flags, pwd1, &err, &msg);
     797           3 :         if (!NT_STATUS_IS_OK(status)) {
     798           0 :                 if (err) fprintf(stderr, "%s", err);
     799           0 :                 ret = -1;
     800           0 :                 goto done;
     801             :         }
     802             : 
     803           3 :         sam_pwent = samu_new(tosctx);
     804           3 :         if (!sam_pwent) {
     805           0 :                 fprintf(stderr, "Out of memory!\n");
     806           0 :                 ret = -1;
     807           0 :                 goto done;
     808             :         }
     809             : 
     810           3 :         if (!pdb_getsampwnam(sam_pwent, username)) {
     811           0 :                 fprintf(stderr, "User %s not found!\n", username);
     812           0 :                 ret = -1;
     813           0 :                 goto done;
     814             :         }
     815             : 
     816           3 :         if (fullname)
     817           0 :                 pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
     818           3 :         if (homedir)
     819           0 :                 pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
     820           3 :         if (drive)
     821           0 :                 pdb_set_dir_drive(sam_pwent, drive, PDB_CHANGED);
     822           3 :         if (script)
     823           0 :                 pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
     824           3 :         if (profile)
     825           0 :                 pdb_set_profile_path(sam_pwent, profile, PDB_CHANGED);
     826           3 :         if (user_sid)
     827           0 :                 pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED);
     828             : 
     829           3 :         status = pdb_update_sam_account(sam_pwent);
     830           3 :         if (!NT_STATUS_IS_OK(status)) {
     831           0 :                 fprintf(stderr,
     832             :                         "Failed to modify entry for user %s.!\n",
     833             :                         username);
     834           0 :                 ret = -1;
     835           0 :                 goto done;
     836             :         }
     837             : 
     838           3 :         print_user_info(username, True, False);
     839           3 :         ret = 0;
     840             : 
     841           3 : done:
     842           3 :         if (pwd1) memset(pwd1, 0, strlen(pwd1));
     843           3 :         if (pwd2) memset(pwd2, 0, strlen(pwd2));
     844           3 :         SAFE_FREE(pwd1);
     845           3 :         SAFE_FREE(pwd2);
     846           3 :         SAFE_FREE(err);
     847           3 :         SAFE_FREE(msg);
     848           3 :         TALLOC_FREE(sam_pwent);
     849           3 :         return ret;
     850             : }
     851             : 
     852             : /*********************************************************
     853             :  Add New Machine
     854             : **********************************************************/
     855             : 
     856           0 : static int new_machine(const char *machinename, char *machine_sid)
     857             : {
     858           0 :         char *err = NULL, *msg = NULL;
     859           0 :         struct samu *sam_pwent = NULL;
     860             :         TALLOC_CTX *tosctx;
     861             :         NTSTATUS status;
     862             :         struct dom_sid m_sid;
     863             :         char *compatpwd;
     864             :         char *name;
     865             :         int flags;
     866             :         int len;
     867             :         int ret;
     868             : 
     869           0 :         len = strlen(machinename);
     870           0 :         if (len == 0) {
     871           0 :                 fprintf(stderr, "No machine name given\n");
     872           0 :                 return -1;
     873             :         }
     874             : 
     875           0 :         tosctx = talloc_tos();
     876           0 :         if (!tosctx) {
     877           0 :                 fprintf(stderr, "Out of memory!\n");
     878           0 :                 return -1;
     879             :         }
     880             : 
     881           0 :         if (machine_sid) {
     882           0 :                 if (get_sid_from_cli_string(&m_sid, machine_sid)) {
     883           0 :                         fprintf(stderr, "Failed to parse SID\n");
     884           0 :                         return -1;
     885             :                 }
     886             :         }
     887             : 
     888           0 :         compatpwd = talloc_strdup(tosctx, machinename);
     889           0 :         if (!compatpwd) {
     890           0 :                 fprintf(stderr, "Out of memory!\n");
     891           0 :                 return -1;
     892             :         }
     893             : 
     894           0 :         if (machinename[len-1] == '$') {
     895           0 :                 name = talloc_strdup(tosctx, machinename);
     896           0 :                 compatpwd[len-1] = '\0';
     897             :         } else {
     898           0 :                 name = talloc_asprintf(tosctx, "%s$", machinename);
     899             :         }
     900           0 :         if (!name) {
     901           0 :                 fprintf(stderr, "Out of memory!\n");
     902           0 :                 return -1;
     903             :         }
     904             : 
     905           0 :         if (!strlower_m(name)) {
     906           0 :                 fprintf(stderr, "strlower_m %s failed\n", name);
     907           0 :                 return -1;
     908             :         }
     909             : 
     910           0 :         flags = LOCAL_ADD_USER | LOCAL_TRUST_ACCOUNT | LOCAL_SET_PASSWORD;
     911             : 
     912           0 :         status = local_password_change(name, flags, compatpwd, &err, &msg);
     913             : 
     914           0 :         if (!NT_STATUS_IS_OK(status)) {
     915           0 :                 if (err) fprintf(stderr, "%s", err);
     916           0 :                 ret = -1;
     917             :         }
     918             : 
     919           0 :         sam_pwent = samu_new(tosctx);
     920           0 :         if (!sam_pwent) {
     921           0 :                 fprintf(stderr, "Out of memory!\n");
     922           0 :                 ret = -1;
     923           0 :                 goto done;
     924             :         }
     925             : 
     926           0 :         if (!pdb_getsampwnam(sam_pwent, name)) {
     927           0 :                 fprintf(stderr, "Machine %s not found!\n", name);
     928           0 :                 ret = -1;
     929           0 :                 goto done;
     930             :         }
     931             : 
     932           0 :         if (machine_sid)
     933           0 :                 pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED);
     934             : 
     935           0 :         status = pdb_update_sam_account(sam_pwent);
     936           0 :         if (!NT_STATUS_IS_OK(status)) {
     937           0 :                 fprintf(stderr,
     938             :                         "Failed to modify entry for %s.!\n", name);
     939           0 :                 ret = -1;
     940           0 :                 goto done;
     941             :         }
     942             : 
     943           0 :         print_user_info(name, True, False);
     944           0 :         ret = 0;
     945             : 
     946           0 : done:
     947           0 :         SAFE_FREE(err);
     948           0 :         SAFE_FREE(msg);
     949           0 :         TALLOC_FREE(sam_pwent);
     950           0 :         return ret;
     951             : }
     952             : 
     953             : /*********************************************************
     954             :  Delete user entry
     955             : **********************************************************/
     956             : 
     957           3 : static int delete_user_entry(const char *username)
     958             : {
     959             :         struct samu *samaccount;
     960             : 
     961           3 :         samaccount = samu_new(NULL);
     962           3 :         if (!samaccount) {
     963           0 :                 fprintf(stderr, "Out of memory!\n");
     964           0 :                 return -1;
     965             :         }
     966             : 
     967           3 :         if (!pdb_getsampwnam(samaccount, username)) {
     968           0 :                 fprintf (stderr,
     969             :                          "user %s does not exist in the passdb\n", username);
     970           0 :                 TALLOC_FREE(samaccount);
     971           0 :                 return -1;
     972             :         }
     973             : 
     974           3 :         if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
     975           0 :                 fprintf (stderr, "Unable to delete user %s\n", username);
     976           0 :                 TALLOC_FREE(samaccount);
     977           0 :                 return -1;
     978             :         }
     979             : 
     980           3 :         TALLOC_FREE(samaccount);
     981           3 :         return 0;
     982             : }
     983             : 
     984             : /*********************************************************
     985             :  Delete machine entry
     986             : **********************************************************/
     987             : 
     988           0 : static int delete_machine_entry(const char *machinename)
     989             : {
     990           0 :         struct samu *samaccount = NULL;
     991             :         const char *name;
     992             : 
     993           0 :         if (strlen(machinename) == 0) {
     994           0 :                 fprintf(stderr, "No machine name given\n");
     995           0 :                 return -1;
     996             :         }
     997             : 
     998           0 :         samaccount = samu_new(NULL);
     999           0 :         if (!samaccount) {
    1000           0 :                 fprintf(stderr, "Out of memory!\n");
    1001           0 :                 return -1;
    1002             :         }
    1003             : 
    1004           0 :         if (machinename[strlen(machinename)-1] != '$') {
    1005           0 :                 name = talloc_asprintf(samaccount, "%s$", machinename);
    1006             :         } else {
    1007           0 :                 name = machinename;
    1008             :         }
    1009             : 
    1010           0 :         if (!pdb_getsampwnam(samaccount, name)) {
    1011           0 :                 fprintf (stderr,
    1012             :                          "machine %s does not exist in the passdb\n", name);
    1013           0 :                 TALLOC_FREE(samaccount);
    1014           0 :                 return -1;
    1015             :         }
    1016             : 
    1017           0 :         if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
    1018           0 :                 fprintf (stderr, "Unable to delete machine %s\n", name);
    1019           0 :                 TALLOC_FREE(samaccount);
    1020           0 :                 return -1;
    1021             :         }
    1022             : 
    1023           0 :         TALLOC_FREE(samaccount);
    1024           0 :         return 0;
    1025             : }
    1026             : 
    1027             : /*********************************************************
    1028             :  Start here.
    1029             : **********************************************************/
    1030             : 
    1031          12 : int main(int argc, const char **argv)
    1032             : {
    1033             :         static int list_users = False;
    1034             :         static int verbose = False;
    1035             :         static int spstyle = False;
    1036             :         static int machine = False;
    1037             :         static int add_user = False;
    1038             :         static int delete_user = False;
    1039             :         static int modify_user = False;
    1040             :         uint32_t   setparms, checkparms;
    1041             :         int opt;
    1042             :         static char *full_name = NULL;
    1043             :         static char *acct_desc = NULL;
    1044             :         static const char *user_name = NULL;
    1045             :         static char *home_dir = NULL;
    1046             :         static char *home_drive = NULL;
    1047             :         static const char *backend = NULL;
    1048             :         static char *backend_in = NULL;
    1049             :         static char *backend_out = NULL;
    1050             :         static int transfer_groups = False;
    1051             :         static int transfer_account_policies = False;
    1052             :         static int reset_account_policies = False;
    1053             :         static int  force_initialised_password = False;
    1054             :         static char *logon_script = NULL;
    1055             :         static char *profile_path = NULL;
    1056             :         static char *user_domain = NULL;
    1057             :         static char *account_control = NULL;
    1058             :         static char *account_policy = NULL;
    1059             :         static char *user_sid = NULL;
    1060             :         static char *machine_sid = NULL;
    1061             :         static long int account_policy_value = 0;
    1062          12 :         bool account_policy_value_set = False;
    1063             :         static int badpw_reset = False;
    1064             :         static int hours_reset = False;
    1065             :         static char *pwd_time_format = NULL;
    1066             :         static int pw_from_stdin = False;
    1067             :         struct pdb_methods *bin, *bout;
    1068             :         static char *kickoff_time = NULL;
    1069             :         static char *str_hex_pwd = NULL;
    1070          12 :         TALLOC_CTX *frame = talloc_stackframe();
    1071          12 :         struct loadparm_context *lp_ctx = NULL;
    1072             :         NTSTATUS status;
    1073             :         poptContext pc;
    1074             :         bool ok;
    1075          36 :         struct poptOption long_options[] = {
    1076             :                 POPT_AUTOHELP
    1077             :                 {"list",      'L', POPT_ARG_NONE, &list_users, 0, "list all users", NULL},
    1078             :                 {"verbose",   'v', POPT_ARG_NONE, &verbose, 0, "be verbose", NULL },
    1079             :                 {"smbpasswd-style",   'w',POPT_ARG_NONE, &spstyle, 0, "give output in smbpasswd style", NULL},
    1080             :                 {"user",      'u', POPT_ARG_STRING, &user_name, 0, "use username", "USER" },
    1081             :                 {"account-desc",      'N', POPT_ARG_STRING, &acct_desc, 0, "set account description", NULL},
    1082             :                 {"fullname",  'f', POPT_ARG_STRING, &full_name, 0, "set full name", NULL},
    1083             :                 {"homedir",   'h', POPT_ARG_STRING, &home_dir, 0, "set home directory", NULL},
    1084             :                 {"drive",     'D', POPT_ARG_STRING, &home_drive, 0, "set home drive", NULL},
    1085             :                 {"script",    'S', POPT_ARG_STRING, &logon_script, 0, "set logon script", NULL},
    1086             :                 {"profile",   'p', POPT_ARG_STRING, &profile_path, 0, "set profile path", NULL},
    1087             :                 {"domain",    'I', POPT_ARG_STRING, &user_domain, 0, "set a users' domain", NULL},
    1088             :                 {"user SID",  'U', POPT_ARG_STRING, &user_sid, 0, "set user SID or RID", NULL},
    1089             :                 {"machine SID",       'M', POPT_ARG_STRING, &machine_sid, 0, "set machine SID or RID", NULL},
    1090             :                 {"create",    'a', POPT_ARG_NONE, &add_user, 0, "create user", NULL},
    1091             :                 {"modify",    'r', POPT_ARG_NONE, &modify_user, 0, "modify user", NULL},
    1092             :                 {"machine",   'm', POPT_ARG_NONE, &machine, 0, "account is a machine account", NULL},
    1093             :                 {"delete",    'x', POPT_ARG_NONE, &delete_user, 0, "delete user", NULL},
    1094             :                 {"backend",   'b', POPT_ARG_STRING, &backend, 0, "use different passdb backend as default backend", NULL},
    1095             :                 {"import",    'i', POPT_ARG_STRING, &backend_in, 0, "import user accounts from this backend", NULL},
    1096             :                 {"export",    'e', POPT_ARG_STRING, &backend_out, 0, "export user accounts to this backend", NULL},
    1097             :                 {"group",     'g', POPT_ARG_NONE, &transfer_groups, 0, "use -i and -e for groups", NULL},
    1098             :                 {"policies",  'y', POPT_ARG_NONE, &transfer_account_policies, 0, "use -i and -e to move account policies between backends", NULL},
    1099             :                 {"policies-reset",    0, POPT_ARG_NONE, &reset_account_policies, 0, "restore default policies", NULL},
    1100             :                 {"account-policy",    'P', POPT_ARG_STRING, &account_policy, 0,"value of an account policy (like maximum password age)",NULL},
    1101             :                 {"value",       'C', POPT_ARG_LONG, &account_policy_value, 'C',"set the account policy to this value", NULL},
    1102             :                 {"account-control",   'c', POPT_ARG_STRING, &account_control, 0, "Values of account control", NULL},
    1103             :                 {"force-initialized-passwords", 0, POPT_ARG_NONE, &force_initialised_password, 0, "Force initialization of corrupt password strings in a passdb backend", NULL},
    1104             :                 {"bad-password-count-reset", 'z', POPT_ARG_NONE, &badpw_reset, 0, "reset bad password count", NULL},
    1105             :                 {"logon-hours-reset", 'Z', POPT_ARG_NONE, &hours_reset, 0, "reset logon hours", NULL},
    1106             :                 {"time-format", 0, POPT_ARG_STRING, &pwd_time_format, 0, "The time format for time parameters", NULL },
    1107             :                 {"password-from-stdin", 't', POPT_ARG_NONE, &pw_from_stdin, 0, "get password from standard in", NULL},
    1108             :                 {"kickoff-time", 'K', POPT_ARG_STRING, &kickoff_time, 0, "set the kickoff time", NULL},
    1109             :                 {"set-nt-hash", 0, POPT_ARG_STRING, &str_hex_pwd, 0, "set password from nt-hash", NULL},
    1110          12 :                 POPT_COMMON_SAMBA
    1111          12 :                 POPT_COMMON_VERSION
    1112             :                 POPT_TABLEEND
    1113             :         };
    1114             : 
    1115          12 :         bin = bout = NULL;
    1116             : 
    1117          12 :         smb_init_locale();
    1118             : 
    1119          12 :         ok = samba_cmdline_init(frame,
    1120             :                                 SAMBA_CMDLINE_CONFIG_CLIENT,
    1121             :                                 false /* require_smbconf */);
    1122          12 :         if (!ok) {
    1123           0 :                 DBG_ERR("Failed to init cmdline parser!\n");
    1124           0 :                 TALLOC_FREE(frame);
    1125           0 :                 exit(1);
    1126             :         }
    1127          12 :         lp_ctx = samba_cmdline_get_lp_ctx();
    1128             : 
    1129          12 :         pc = samba_popt_get_context(getprogname(),
    1130             :                                     argc,
    1131             :                                     argv,
    1132             :                                     long_options,
    1133             :                                     POPT_CONTEXT_KEEP_FIRST);
    1134          12 :         if (pc == NULL) {
    1135           0 :                 DBG_ERR("Failed to setup popt context!\n");
    1136           0 :                 TALLOC_FREE(frame);
    1137           0 :                 exit(1);
    1138             :         }
    1139             : 
    1140          12 :         while((opt = poptGetNextOpt(pc)) != -1) {
    1141           0 :                 switch (opt) {
    1142           0 :                 case 'C':
    1143           0 :                         account_policy_value_set = True;
    1144           0 :                         break;
    1145           0 :                 case POPT_ERROR_BADOPT:
    1146           0 :                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
    1147             :                                 poptBadOption(pc, 0), poptStrerror(opt));
    1148           0 :                         poptPrintUsage(pc, stderr, 0);
    1149           0 :                         exit(1);
    1150             :                 }
    1151             :         }
    1152             : 
    1153          12 :         poptGetArg(pc); /* Drop argv[0], the program name */
    1154             : 
    1155          12 :         if (user_name == NULL) {
    1156           9 :                 if (poptPeekArg(pc)) {
    1157           9 :                         user_name = talloc_strdup(frame, poptGetArg(pc));
    1158           9 :                         if (user_name == NULL) {
    1159           0 :                                 fprintf(stderr, "out of memory\n");
    1160           0 :                                 TALLOC_FREE(frame);
    1161           0 :                                 exit(1);
    1162             :                         }
    1163             :                 }
    1164             :         }
    1165             : 
    1166          12 :         setparms =      (backend ? BIT_BACKEND : 0) +
    1167          12 :                         (verbose ? BIT_VERBOSE : 0) +
    1168          12 :                         (spstyle ? BIT_SPSTYLE : 0) +
    1169          12 :                         (full_name ? BIT_FULLNAME : 0) +
    1170          12 :                         (home_dir ? BIT_HOMEDIR : 0) +
    1171          12 :                         (home_drive ? BIT_HDIRDRIVE : 0) +
    1172          12 :                         (logon_script ? BIT_LOGSCRIPT : 0) +
    1173          12 :                         (profile_path ? BIT_PROFILE : 0) +
    1174          12 :                         (user_domain ? BIT_USERDOMAIN : 0) +
    1175          12 :                         (machine ? BIT_MACHINE : 0) +
    1176          12 :                         (user_name ? BIT_USER : 0) +
    1177          12 :                         (list_users ? BIT_LIST : 0) +
    1178          12 :                         (force_initialised_password ? BIT_FIX_INIT : 0) +
    1179          12 :                         (user_sid ? BIT_USERSIDS : 0) +
    1180          12 :                         (machine_sid ? BIT_USERSIDS : 0) +
    1181          12 :                         (modify_user ? BIT_MODIFY : 0) +
    1182          12 :                         (add_user ? BIT_CREATE : 0) +
    1183          12 :                         (delete_user ? BIT_DELETE : 0) +
    1184          12 :                         (account_control ? BIT_ACCTCTRL : 0) +
    1185          12 :                         (account_policy ? BIT_ACCPOLICY : 0) +
    1186          12 :                         (account_policy_value_set ? BIT_ACCPOLVAL : 0) +
    1187          12 :                         (backend_in ? BIT_IMPORT : 0) +
    1188          12 :                         (backend_out ? BIT_EXPORT : 0) +
    1189          12 :                         (badpw_reset ? BIT_BADPWRESET : 0) +
    1190          12 :                         (hours_reset ? BIT_LOGONHOURS : 0) +
    1191          12 :                         (kickoff_time ? BIT_KICKOFFTIME : 0) +
    1192          12 :                         (str_hex_pwd ? BIT_PWSETNTHASH : 0 ) +
    1193          12 :                         (acct_desc ? BIT_DESCRIPTION : 0);
    1194             : 
    1195             : 
    1196          12 :         if (setparms & BIT_BACKEND) {
    1197             :                 /* HACK: set the global passdb backend by overwriting globals.
    1198             :                  * This way we can use regular pdb functions for default
    1199             :                  * operations that do not involve passdb migrations */
    1200           0 :                 lpcfg_set_cmdline(lp_ctx, "passdb backend", backend);
    1201             :         } else {
    1202          12 :                 backend = lp_passdb_backend();
    1203             :         }
    1204             : 
    1205          12 :         if (!initialize_password_db(False, NULL)) {
    1206           0 :                 fprintf(stderr, "Can't initialize passdb backend.\n");
    1207           0 :                 exit(1);
    1208             :         }
    1209             : 
    1210             :         /* the lowest bit options are always accepted */
    1211          12 :         checkparms = setparms & ~MASK_ALWAYS_GOOD;
    1212             : 
    1213          12 :         if (checkparms & BIT_FIX_INIT) {
    1214           0 :                 poptFreeContext(pc);
    1215           0 :                 return fix_users_list();
    1216             :         }
    1217             : 
    1218             :         /* account policy operations */
    1219          12 :         if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) {
    1220             :                 uint32_t value;
    1221           0 :                 enum pdb_policy_type field = account_policy_name_to_typenum(account_policy);
    1222           0 :                 if (field == 0) {
    1223             :                         const char **names;
    1224             :                         int count;
    1225             :                         int i;
    1226           0 :                         account_policy_names_list(talloc_tos(), &names, &count);
    1227           0 :                         fprintf(stderr, "No account policy by that name!\n");
    1228           0 :                         if (count !=0) {
    1229           0 :                                 fprintf(stderr, "Account policy names are:\n");
    1230           0 :                                 for (i = 0; i < count ; i++) {
    1231           0 :                                         d_fprintf(stderr, "%s\n", names[i]);
    1232             :                                 }
    1233             :                         }
    1234           0 :                         TALLOC_FREE(names);
    1235           0 :                         exit(1);
    1236             :                 }
    1237           0 :                 if (!pdb_get_account_policy(field, &value)) {
    1238           0 :                         fprintf(stderr, "valid account policy, but unable to fetch value!\n");
    1239           0 :                         if (!account_policy_value_set)
    1240           0 :                                 exit(1);
    1241             :                 }
    1242           0 :                 printf("account policy \"%s\" description: %s\n", account_policy, account_policy_get_desc(field));
    1243           0 :                 if (account_policy_value_set) {
    1244           0 :                         printf("account policy \"%s\" value was: %u\n", account_policy, value);
    1245           0 :                         if (!pdb_set_account_policy(field, account_policy_value)) {
    1246           0 :                                 fprintf(stderr, "valid account policy, but unable to set value!\n");
    1247           0 :                                 exit(1);
    1248             :                         }
    1249           0 :                         printf("account policy \"%s\" value is now: %lu\n", account_policy, account_policy_value);
    1250           0 :                         exit(0);
    1251             :                 } else {
    1252           0 :                         printf("account policy \"%s\" value is: %u\n", account_policy, value);
    1253           0 :                         exit(0);
    1254             :                 }
    1255             :         }
    1256             : 
    1257          12 :         if (reset_account_policies) {
    1258           0 :                 if (reinit_account_policies()) {
    1259           0 :                         exit(1);
    1260             :                 }
    1261             : 
    1262           0 :                 exit(0);
    1263             :         }
    1264             : 
    1265             :         /* import and export operations */
    1266             : 
    1267          12 :         if (((checkparms & BIT_IMPORT) ||
    1268          12 :              (checkparms & BIT_EXPORT)) &&
    1269           0 :             !(checkparms & ~(BIT_IMPORT +BIT_EXPORT +BIT_USER))) {
    1270             : 
    1271           0 :                 poptFreeContext(pc);
    1272             : 
    1273           0 :                 if (backend_in) {
    1274           0 :                         status = make_pdb_method_name(&bin, backend_in);
    1275             :                 } else {
    1276           0 :                         status = make_pdb_method_name(&bin, backend);
    1277             :                 }
    1278             : 
    1279           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1280           0 :                         fprintf(stderr, "Unable to initialize %s.\n",
    1281           0 :                                 backend_in ? backend_in : backend);
    1282           0 :                         return 1;
    1283             :                 }
    1284             : 
    1285           0 :                 if (backend_out) {
    1286           0 :                         status = make_pdb_method_name(&bout, backend_out);
    1287             :                 } else {
    1288           0 :                         status = make_pdb_method_name(&bout, backend);
    1289             :                 }
    1290             : 
    1291           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1292           0 :                         fprintf(stderr, "Unable to initialize %s.\n",
    1293           0 :                                 backend_out ? backend_out : backend);
    1294           0 :                         return 1;
    1295             :                 }
    1296             : 
    1297           0 :                 if (transfer_account_policies) {
    1298             : 
    1299           0 :                         if (!(checkparms & BIT_USER)) {
    1300           0 :                                 return export_account_policies(bin, bout);
    1301             :                         }
    1302             : 
    1303           0 :                 } else  if (transfer_groups) {
    1304             : 
    1305           0 :                         if (!(checkparms & BIT_USER)) {
    1306           0 :                                 return export_groups(bin, bout);
    1307             :                         }
    1308             : 
    1309             :                 } else {
    1310           0 :                         return export_database(bin, bout,
    1311           0 :                                 (checkparms & BIT_USER) ? user_name : NULL);
    1312             :                 }
    1313             :         }
    1314             : 
    1315             :         /* if BIT_USER is defined but nothing else then threat it as -l -u for compatibility */
    1316             :         /* fake up BIT_LIST if only BIT_USER is defined */
    1317          12 :         if ((checkparms & BIT_USER) && !(checkparms & ~BIT_USER)) {
    1318           0 :                 checkparms += BIT_LIST;
    1319             :         }
    1320             : 
    1321             :         /* modify flag is optional to maintain backwards compatibility */
    1322             :         /* fake up BIT_MODIFY if BIT_USER  and at least one of MASK_USER_GOOD is defined */
    1323          12 :         if (!((checkparms & ~MASK_USER_GOOD) & ~BIT_USER) && (checkparms & MASK_USER_GOOD)) {
    1324           3 :                 checkparms += BIT_MODIFY;
    1325             :         }
    1326             : 
    1327             :         /* list users operations */
    1328          12 :         if (checkparms & BIT_LIST) {
    1329           0 :                 if (!(checkparms & ~BIT_LIST)) {
    1330           0 :                         poptFreeContext(pc);
    1331           0 :                         return print_users_list(verbose, spstyle);
    1332             :                 }
    1333           0 :                 if (!(checkparms & ~(BIT_USER + BIT_LIST))) {
    1334           0 :                         poptFreeContext(pc);
    1335           0 :                         return print_user_info(user_name, verbose, spstyle);
    1336             :                 }
    1337             :         }
    1338             : 
    1339             :         /* mask out users options */
    1340          12 :         checkparms &= ~MASK_USER_GOOD;
    1341             : 
    1342             :         /* if bad password count is reset, we must be modifying */
    1343          12 :         if (checkparms & BIT_BADPWRESET) {
    1344           0 :                 checkparms |= BIT_MODIFY;
    1345           0 :                 checkparms &= ~BIT_BADPWRESET;
    1346             :         }
    1347             : 
    1348             :         /* if logon hours is reset, must modify */
    1349          12 :         if (checkparms & BIT_LOGONHOURS) {
    1350           0 :                 checkparms |= BIT_MODIFY;
    1351           0 :                 checkparms &= ~BIT_LOGONHOURS;
    1352             :         }
    1353             : 
    1354             :         /* account operation */
    1355          12 :         if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) {
    1356             :                 /* check use of -u option */
    1357          12 :                 if (!(checkparms & BIT_USER)) {
    1358           0 :                         fprintf (stderr, "Username not specified! (use -u option)\n");
    1359           0 :                         poptFreeContext(pc);
    1360           0 :                         return -1;
    1361             :                 }
    1362             : 
    1363             :                 /* account creation operations */
    1364          12 :                 if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE))) {
    1365           3 :                         poptFreeContext(pc);
    1366           3 :                         if (checkparms & BIT_MACHINE) {
    1367           0 :                                 return new_machine(user_name, machine_sid);
    1368             :                         } else {
    1369           3 :                                 return new_user(user_name, full_name,
    1370             :                                                 home_dir, home_drive,
    1371             :                                                 logon_script, profile_path,
    1372             :                                                 user_sid, pw_from_stdin);
    1373             :                         }
    1374             :                 }
    1375             : 
    1376             :                 /* account deletion operations */
    1377           9 :                 if (!(checkparms & ~(BIT_DELETE + BIT_USER + BIT_MACHINE))) {
    1378           3 :                         poptFreeContext(pc);
    1379           3 :                         if (checkparms & BIT_MACHINE) {
    1380           0 :                                 return delete_machine_entry(user_name);
    1381             :                         } else {
    1382           3 :                                 return delete_user_entry(user_name);
    1383             :                         }
    1384             :                 }
    1385             : 
    1386             :                 /* account modification operations */
    1387           6 :                 if (!(checkparms & ~(BIT_MODIFY + BIT_USER + BIT_MACHINE))) {
    1388           6 :                         poptFreeContext(pc);
    1389           6 :                         if (checkparms & BIT_MACHINE) {
    1390           0 :                                 return set_machine_info(user_name,
    1391             :                                                         account_control,
    1392             :                                                         machine_sid);
    1393             :                         } else {
    1394           6 :                                 return set_user_info(user_name, full_name,
    1395             :                                                      home_dir, acct_desc,
    1396             :                                                      home_drive, logon_script,
    1397             :                                                      profile_path, account_control,
    1398             :                                                      user_sid, user_domain,
    1399             :                                                      badpw_reset, hours_reset,
    1400             :                                                      kickoff_time, str_hex_pwd);
    1401             :                         }
    1402             :                 }
    1403             :         }
    1404             : 
    1405           0 :         if (setparms >= 0x20) {
    1406           0 :                 fprintf (stderr, "Incompatible or insufficient options on command line!\n");
    1407             :         }
    1408           0 :         poptPrintHelp(pc, stderr, 0);
    1409             : 
    1410           0 :         gfree_all();
    1411           0 :         poptFreeContext(pc);
    1412           0 :         TALLOC_FREE(frame);
    1413           0 :         return 1;
    1414             : }

Generated by: LCOV version 1.14