LCOV - code coverage report
Current view: top level - source3/utils - pdbedit.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 214 686 31.2 %
Date: 2024-04-21 15:09:00 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             :         uint32_t value;
     765             : 
     766           3 :         tosctx = talloc_tos();
     767           3 :         if (!tosctx) {
     768           0 :                 fprintf(stderr, "Out of memory!\n");
     769           0 :                 return -1;
     770             :         }
     771             : 
     772           3 :         if (user_sid) {
     773           0 :                 if (get_sid_from_cli_string(&u_sid, user_sid)) {
     774           0 :                         fprintf(stderr, "Failed to parse SID\n");
     775           0 :                         return -1;
     776             :                 }
     777             :         }
     778             : 
     779           3 :         pwd1 = get_pass( "new password:", stdin_get);
     780           3 :         if (pwd1 == NULL) {
     781           0 :                 fprintf(stderr, "Failed to read passwords.\n");
     782           0 :                 goto done;
     783             :         }
     784           3 :         pwd2 = get_pass( "retype new password:", stdin_get);
     785           3 :         if (pwd2 == NULL) {
     786           0 :                 fprintf(stderr, "Failed to read passwords.\n");
     787           0 :                 goto done;
     788             :         }
     789           3 :         ret = strcmp(pwd1, pwd2);
     790           3 :         if (ret != 0) {
     791           0 :                 fprintf (stderr, "Passwords do not match!\n");
     792           0 :                 goto done;
     793             :         }
     794             : 
     795           3 :         if(!account_policy_get(PDB_POLICY_MIN_PASSWORD_LEN, &value)) {
     796           0 :                 fprintf (stderr, "Failed to get min password length!\n");
     797           0 :                 goto done;
     798             :         }
     799             : 
     800           3 :         if(value > strlen(pwd1)) {
     801           0 :                 fprintf (stderr, "Password is too short!\n");
     802           0 :                 goto done;
     803             :         }
     804             : 
     805           3 :         flags = LOCAL_ADD_USER | LOCAL_SET_PASSWORD;
     806             : 
     807           3 :         status = local_password_change(username, flags, pwd1, &err, &msg);
     808           3 :         if (!NT_STATUS_IS_OK(status)) {
     809           0 :                 if (err) fprintf(stderr, "%s", err);
     810           0 :                 ret = -1;
     811           0 :                 goto done;
     812             :         }
     813             : 
     814           3 :         sam_pwent = samu_new(tosctx);
     815           3 :         if (!sam_pwent) {
     816           0 :                 fprintf(stderr, "Out of memory!\n");
     817           0 :                 ret = -1;
     818           0 :                 goto done;
     819             :         }
     820             : 
     821           3 :         if (!pdb_getsampwnam(sam_pwent, username)) {
     822           0 :                 fprintf(stderr, "User %s not found!\n", username);
     823           0 :                 ret = -1;
     824           0 :                 goto done;
     825             :         }
     826             : 
     827           3 :         if (fullname)
     828           0 :                 pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
     829           3 :         if (homedir)
     830           0 :                 pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
     831           3 :         if (drive)
     832           0 :                 pdb_set_dir_drive(sam_pwent, drive, PDB_CHANGED);
     833           3 :         if (script)
     834           0 :                 pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
     835           3 :         if (profile)
     836           0 :                 pdb_set_profile_path(sam_pwent, profile, PDB_CHANGED);
     837           3 :         if (user_sid)
     838           0 :                 pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED);
     839             : 
     840           3 :         status = pdb_update_sam_account(sam_pwent);
     841           3 :         if (!NT_STATUS_IS_OK(status)) {
     842           0 :                 fprintf(stderr,
     843             :                         "Failed to modify entry for user %s.!\n",
     844             :                         username);
     845           0 :                 ret = -1;
     846           0 :                 goto done;
     847             :         }
     848             : 
     849           3 :         print_user_info(username, True, False);
     850           3 :         ret = 0;
     851             : 
     852           3 : done:
     853           3 :         if (pwd1) memset(pwd1, 0, strlen(pwd1));
     854           3 :         if (pwd2) memset(pwd2, 0, strlen(pwd2));
     855           3 :         SAFE_FREE(pwd1);
     856           3 :         SAFE_FREE(pwd2);
     857           3 :         SAFE_FREE(err);
     858           3 :         SAFE_FREE(msg);
     859           3 :         TALLOC_FREE(sam_pwent);
     860           3 :         return ret;
     861             : }
     862             : 
     863             : /*********************************************************
     864             :  Add New Machine
     865             : **********************************************************/
     866             : 
     867           0 : static int new_machine(const char *machinename, char *machine_sid)
     868             : {
     869           0 :         char *err = NULL, *msg = NULL;
     870           0 :         struct samu *sam_pwent = NULL;
     871             :         TALLOC_CTX *tosctx;
     872             :         NTSTATUS status;
     873             :         struct dom_sid m_sid;
     874             :         char *compatpwd;
     875             :         char *name;
     876             :         int flags;
     877             :         int len;
     878             :         int ret;
     879             : 
     880           0 :         len = strlen(machinename);
     881           0 :         if (len == 0) {
     882           0 :                 fprintf(stderr, "No machine name given\n");
     883           0 :                 return -1;
     884             :         }
     885             : 
     886           0 :         tosctx = talloc_tos();
     887           0 :         if (!tosctx) {
     888           0 :                 fprintf(stderr, "Out of memory!\n");
     889           0 :                 return -1;
     890             :         }
     891             : 
     892           0 :         if (machine_sid) {
     893           0 :                 if (get_sid_from_cli_string(&m_sid, machine_sid)) {
     894           0 :                         fprintf(stderr, "Failed to parse SID\n");
     895           0 :                         return -1;
     896             :                 }
     897             :         }
     898             : 
     899           0 :         compatpwd = talloc_strdup(tosctx, machinename);
     900           0 :         if (!compatpwd) {
     901           0 :                 fprintf(stderr, "Out of memory!\n");
     902           0 :                 return -1;
     903             :         }
     904             : 
     905           0 :         if (machinename[len-1] == '$') {
     906           0 :                 name = talloc_strdup(tosctx, machinename);
     907           0 :                 compatpwd[len-1] = '\0';
     908             :         } else {
     909           0 :                 name = talloc_asprintf(tosctx, "%s$", machinename);
     910             :         }
     911           0 :         if (!name) {
     912           0 :                 fprintf(stderr, "Out of memory!\n");
     913           0 :                 return -1;
     914             :         }
     915             : 
     916           0 :         if (!strlower_m(name)) {
     917           0 :                 fprintf(stderr, "strlower_m %s failed\n", name);
     918           0 :                 return -1;
     919             :         }
     920             : 
     921           0 :         flags = LOCAL_ADD_USER | LOCAL_TRUST_ACCOUNT | LOCAL_SET_PASSWORD;
     922             : 
     923           0 :         status = local_password_change(name, flags, compatpwd, &err, &msg);
     924             : 
     925           0 :         if (!NT_STATUS_IS_OK(status)) {
     926           0 :                 if (err) fprintf(stderr, "%s", err);
     927           0 :                 ret = -1;
     928             :         }
     929             : 
     930           0 :         sam_pwent = samu_new(tosctx);
     931           0 :         if (!sam_pwent) {
     932           0 :                 fprintf(stderr, "Out of memory!\n");
     933           0 :                 ret = -1;
     934           0 :                 goto done;
     935             :         }
     936             : 
     937           0 :         if (!pdb_getsampwnam(sam_pwent, name)) {
     938           0 :                 fprintf(stderr, "Machine %s not found!\n", name);
     939           0 :                 ret = -1;
     940           0 :                 goto done;
     941             :         }
     942             : 
     943           0 :         if (machine_sid)
     944           0 :                 pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED);
     945             : 
     946           0 :         status = pdb_update_sam_account(sam_pwent);
     947           0 :         if (!NT_STATUS_IS_OK(status)) {
     948           0 :                 fprintf(stderr,
     949             :                         "Failed to modify entry for %s.!\n", name);
     950           0 :                 ret = -1;
     951           0 :                 goto done;
     952             :         }
     953             : 
     954           0 :         print_user_info(name, True, False);
     955           0 :         ret = 0;
     956             : 
     957           0 : done:
     958           0 :         SAFE_FREE(err);
     959           0 :         SAFE_FREE(msg);
     960           0 :         TALLOC_FREE(sam_pwent);
     961           0 :         return ret;
     962             : }
     963             : 
     964             : /*********************************************************
     965             :  Delete user entry
     966             : **********************************************************/
     967             : 
     968           3 : static int delete_user_entry(const char *username)
     969             : {
     970             :         struct samu *samaccount;
     971             : 
     972           3 :         samaccount = samu_new(NULL);
     973           3 :         if (!samaccount) {
     974           0 :                 fprintf(stderr, "Out of memory!\n");
     975           0 :                 return -1;
     976             :         }
     977             : 
     978           3 :         if (!pdb_getsampwnam(samaccount, username)) {
     979           0 :                 fprintf (stderr,
     980             :                          "user %s does not exist in the passdb\n", username);
     981           0 :                 TALLOC_FREE(samaccount);
     982           0 :                 return -1;
     983             :         }
     984             : 
     985           3 :         if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
     986           0 :                 fprintf (stderr, "Unable to delete user %s\n", username);
     987           0 :                 TALLOC_FREE(samaccount);
     988           0 :                 return -1;
     989             :         }
     990             : 
     991           3 :         TALLOC_FREE(samaccount);
     992           3 :         return 0;
     993             : }
     994             : 
     995             : /*********************************************************
     996             :  Delete machine entry
     997             : **********************************************************/
     998             : 
     999           0 : static int delete_machine_entry(const char *machinename)
    1000             : {
    1001           0 :         struct samu *samaccount = NULL;
    1002             :         const char *name;
    1003             : 
    1004           0 :         if (strlen(machinename) == 0) {
    1005           0 :                 fprintf(stderr, "No machine name given\n");
    1006           0 :                 return -1;
    1007             :         }
    1008             : 
    1009           0 :         samaccount = samu_new(NULL);
    1010           0 :         if (!samaccount) {
    1011           0 :                 fprintf(stderr, "Out of memory!\n");
    1012           0 :                 return -1;
    1013             :         }
    1014             : 
    1015           0 :         if (machinename[strlen(machinename)-1] != '$') {
    1016           0 :                 name = talloc_asprintf(samaccount, "%s$", machinename);
    1017             :         } else {
    1018           0 :                 name = machinename;
    1019             :         }
    1020             : 
    1021           0 :         if (!pdb_getsampwnam(samaccount, name)) {
    1022           0 :                 fprintf (stderr,
    1023             :                          "machine %s does not exist in the passdb\n", name);
    1024           0 :                 TALLOC_FREE(samaccount);
    1025           0 :                 return -1;
    1026             :         }
    1027             : 
    1028           0 :         if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
    1029           0 :                 fprintf (stderr, "Unable to delete machine %s\n", name);
    1030           0 :                 TALLOC_FREE(samaccount);
    1031           0 :                 return -1;
    1032             :         }
    1033             : 
    1034           0 :         TALLOC_FREE(samaccount);
    1035           0 :         return 0;
    1036             : }
    1037             : 
    1038             : /*********************************************************
    1039             :  Start here.
    1040             : **********************************************************/
    1041             : 
    1042          12 : int main(int argc, const char **argv)
    1043             : {
    1044             :         static int list_users = False;
    1045             :         static int verbose = False;
    1046             :         static int spstyle = False;
    1047             :         static int machine = False;
    1048             :         static int add_user = False;
    1049             :         static int delete_user = False;
    1050             :         static int modify_user = False;
    1051             :         uint32_t   setparms, checkparms;
    1052             :         int opt;
    1053             :         static char *full_name = NULL;
    1054             :         static char *acct_desc = NULL;
    1055             :         static const char *user_name = NULL;
    1056             :         static char *home_dir = NULL;
    1057             :         static char *home_drive = NULL;
    1058             :         static const char *backend = NULL;
    1059             :         static char *backend_in = NULL;
    1060             :         static char *backend_out = NULL;
    1061             :         static int transfer_groups = False;
    1062             :         static int transfer_account_policies = False;
    1063             :         static int reset_account_policies = False;
    1064             :         static int  force_initialised_password = False;
    1065             :         static char *logon_script = NULL;
    1066             :         static char *profile_path = NULL;
    1067             :         static char *user_domain = NULL;
    1068             :         static char *account_control = NULL;
    1069             :         static char *account_policy = NULL;
    1070             :         static char *user_sid = NULL;
    1071             :         static char *machine_sid = NULL;
    1072             :         static long int account_policy_value = 0;
    1073          12 :         bool account_policy_value_set = False;
    1074             :         static int badpw_reset = False;
    1075             :         static int hours_reset = False;
    1076             :         static char *pwd_time_format = NULL;
    1077             :         static int pw_from_stdin = False;
    1078             :         struct pdb_methods *bin, *bout;
    1079             :         static char *kickoff_time = NULL;
    1080             :         static char *str_hex_pwd = NULL;
    1081          12 :         TALLOC_CTX *frame = talloc_stackframe();
    1082          12 :         struct loadparm_context *lp_ctx = NULL;
    1083             :         NTSTATUS status;
    1084             :         poptContext pc;
    1085             :         bool ok;
    1086          36 :         struct poptOption long_options[] = {
    1087             :                 POPT_AUTOHELP
    1088             :                 {"list",      'L', POPT_ARG_NONE, &list_users, 0, "list all users", NULL},
    1089             :                 {"verbose",   'v', POPT_ARG_NONE, &verbose, 0, "be verbose", NULL },
    1090             :                 {"smbpasswd-style",   'w',POPT_ARG_NONE, &spstyle, 0, "give output in smbpasswd style", NULL},
    1091             :                 {"user",      'u', POPT_ARG_STRING, &user_name, 0, "use username", "USER" },
    1092             :                 {"account-desc",      'N', POPT_ARG_STRING, &acct_desc, 0, "set account description", NULL},
    1093             :                 {"fullname",  'f', POPT_ARG_STRING, &full_name, 0, "set full name", NULL},
    1094             :                 {"homedir",   'h', POPT_ARG_STRING, &home_dir, 0, "set home directory", NULL},
    1095             :                 {"drive",     'D', POPT_ARG_STRING, &home_drive, 0, "set home drive", NULL},
    1096             :                 {"script",    'S', POPT_ARG_STRING, &logon_script, 0, "set logon script", NULL},
    1097             :                 {"profile",   'p', POPT_ARG_STRING, &profile_path, 0, "set profile path", NULL},
    1098             :                 {"domain",    'I', POPT_ARG_STRING, &user_domain, 0, "set a users' domain", NULL},
    1099             :                 {"user SID",  'U', POPT_ARG_STRING, &user_sid, 0, "set user SID or RID", NULL},
    1100             :                 {"machine SID",       'M', POPT_ARG_STRING, &machine_sid, 0, "set machine SID or RID", NULL},
    1101             :                 {"create",    'a', POPT_ARG_NONE, &add_user, 0, "create user", NULL},
    1102             :                 {"modify",    'r', POPT_ARG_NONE, &modify_user, 0, "modify user", NULL},
    1103             :                 {"machine",   'm', POPT_ARG_NONE, &machine, 0, "account is a machine account", NULL},
    1104             :                 {"delete",    'x', POPT_ARG_NONE, &delete_user, 0, "delete user", NULL},
    1105             :                 {"backend",   'b', POPT_ARG_STRING, &backend, 0, "use different passdb backend as default backend", NULL},
    1106             :                 {"import",    'i', POPT_ARG_STRING, &backend_in, 0, "import user accounts from this backend", NULL},
    1107             :                 {"export",    'e', POPT_ARG_STRING, &backend_out, 0, "export user accounts to this backend", NULL},
    1108             :                 {"group",     'g', POPT_ARG_NONE, &transfer_groups, 0, "use -i and -e for groups", NULL},
    1109             :                 {"policies",  'y', POPT_ARG_NONE, &transfer_account_policies, 0, "use -i and -e to move account policies between backends", NULL},
    1110             :                 {"policies-reset",    0, POPT_ARG_NONE, &reset_account_policies, 0, "restore default policies", NULL},
    1111             :                 {"account-policy",    'P', POPT_ARG_STRING, &account_policy, 0,"value of an account policy (like maximum password age)",NULL},
    1112             :                 {"value",       'C', POPT_ARG_LONG, &account_policy_value, 'C',"set the account policy to this value", NULL},
    1113             :                 {"account-control",   'c', POPT_ARG_STRING, &account_control, 0, "Values of account control", NULL},
    1114             :                 {"force-initialized-passwords", 0, POPT_ARG_NONE, &force_initialised_password, 0, "Force initialization of corrupt password strings in a passdb backend", NULL},
    1115             :                 {"bad-password-count-reset", 'z', POPT_ARG_NONE, &badpw_reset, 0, "reset bad password count", NULL},
    1116             :                 {"logon-hours-reset", 'Z', POPT_ARG_NONE, &hours_reset, 0, "reset logon hours", NULL},
    1117             :                 {"time-format", 0, POPT_ARG_STRING, &pwd_time_format, 0, "The time format for time parameters", NULL },
    1118             :                 {"password-from-stdin", 't', POPT_ARG_NONE, &pw_from_stdin, 0, "get password from standard in", NULL},
    1119             :                 {"kickoff-time", 'K', POPT_ARG_STRING, &kickoff_time, 0, "set the kickoff time", NULL},
    1120             :                 {"set-nt-hash", 0, POPT_ARG_STRING, &str_hex_pwd, 0, "set password from nt-hash", NULL},
    1121          12 :                 POPT_COMMON_SAMBA
    1122          12 :                 POPT_COMMON_VERSION
    1123             :                 POPT_TABLEEND
    1124             :         };
    1125             : 
    1126          12 :         bin = bout = NULL;
    1127             : 
    1128          12 :         smb_init_locale();
    1129             : 
    1130          12 :         ok = samba_cmdline_init(frame,
    1131             :                                 SAMBA_CMDLINE_CONFIG_CLIENT,
    1132             :                                 false /* require_smbconf */);
    1133          12 :         if (!ok) {
    1134           0 :                 DBG_ERR("Failed to init cmdline parser!\n");
    1135           0 :                 TALLOC_FREE(frame);
    1136           0 :                 exit(1);
    1137             :         }
    1138          12 :         lp_ctx = samba_cmdline_get_lp_ctx();
    1139             : 
    1140          12 :         pc = samba_popt_get_context(getprogname(),
    1141             :                                     argc,
    1142             :                                     argv,
    1143             :                                     long_options,
    1144             :                                     POPT_CONTEXT_KEEP_FIRST);
    1145          12 :         if (pc == NULL) {
    1146           0 :                 DBG_ERR("Failed to setup popt context!\n");
    1147           0 :                 TALLOC_FREE(frame);
    1148           0 :                 exit(1);
    1149             :         }
    1150             : 
    1151          12 :         while((opt = poptGetNextOpt(pc)) != -1) {
    1152           0 :                 switch (opt) {
    1153           0 :                 case 'C':
    1154           0 :                         account_policy_value_set = True;
    1155           0 :                         break;
    1156           0 :                 case POPT_ERROR_BADOPT:
    1157           0 :                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
    1158             :                                 poptBadOption(pc, 0), poptStrerror(opt));
    1159           0 :                         poptPrintUsage(pc, stderr, 0);
    1160           0 :                         exit(1);
    1161             :                 }
    1162             :         }
    1163             : 
    1164          12 :         poptGetArg(pc); /* Drop argv[0], the program name */
    1165             : 
    1166          12 :         if (user_name == NULL) {
    1167           9 :                 if (poptPeekArg(pc)) {
    1168           9 :                         user_name = talloc_strdup(frame, poptGetArg(pc));
    1169           9 :                         if (user_name == NULL) {
    1170           0 :                                 fprintf(stderr, "out of memory\n");
    1171           0 :                                 TALLOC_FREE(frame);
    1172           0 :                                 exit(1);
    1173             :                         }
    1174             :                 }
    1175             :         }
    1176             : 
    1177          12 :         setparms =      (backend ? BIT_BACKEND : 0) +
    1178          12 :                         (verbose ? BIT_VERBOSE : 0) +
    1179          12 :                         (spstyle ? BIT_SPSTYLE : 0) +
    1180          12 :                         (full_name ? BIT_FULLNAME : 0) +
    1181          12 :                         (home_dir ? BIT_HOMEDIR : 0) +
    1182          12 :                         (home_drive ? BIT_HDIRDRIVE : 0) +
    1183          12 :                         (logon_script ? BIT_LOGSCRIPT : 0) +
    1184          12 :                         (profile_path ? BIT_PROFILE : 0) +
    1185          12 :                         (user_domain ? BIT_USERDOMAIN : 0) +
    1186          12 :                         (machine ? BIT_MACHINE : 0) +
    1187          12 :                         (user_name ? BIT_USER : 0) +
    1188          12 :                         (list_users ? BIT_LIST : 0) +
    1189          12 :                         (force_initialised_password ? BIT_FIX_INIT : 0) +
    1190          12 :                         (user_sid ? BIT_USERSIDS : 0) +
    1191          12 :                         (machine_sid ? BIT_USERSIDS : 0) +
    1192          12 :                         (modify_user ? BIT_MODIFY : 0) +
    1193          12 :                         (add_user ? BIT_CREATE : 0) +
    1194          12 :                         (delete_user ? BIT_DELETE : 0) +
    1195          12 :                         (account_control ? BIT_ACCTCTRL : 0) +
    1196          12 :                         (account_policy ? BIT_ACCPOLICY : 0) +
    1197          12 :                         (account_policy_value_set ? BIT_ACCPOLVAL : 0) +
    1198          12 :                         (backend_in ? BIT_IMPORT : 0) +
    1199          12 :                         (backend_out ? BIT_EXPORT : 0) +
    1200          12 :                         (badpw_reset ? BIT_BADPWRESET : 0) +
    1201          12 :                         (hours_reset ? BIT_LOGONHOURS : 0) +
    1202          12 :                         (kickoff_time ? BIT_KICKOFFTIME : 0) +
    1203          12 :                         (str_hex_pwd ? BIT_PWSETNTHASH : 0 ) +
    1204          12 :                         (acct_desc ? BIT_DESCRIPTION : 0);
    1205             : 
    1206             : 
    1207          12 :         if (setparms & BIT_BACKEND) {
    1208             :                 /* HACK: set the global passdb backend by overwriting globals.
    1209             :                  * This way we can use regular pdb functions for default
    1210             :                  * operations that do not involve passdb migrations */
    1211           0 :                 lpcfg_set_cmdline(lp_ctx, "passdb backend", backend);
    1212             :         } else {
    1213          12 :                 backend = lp_passdb_backend();
    1214             :         }
    1215             : 
    1216          12 :         if (!initialize_password_db(False, NULL)) {
    1217           0 :                 fprintf(stderr, "Can't initialize passdb backend.\n");
    1218           0 :                 exit(1);
    1219             :         }
    1220             : 
    1221             :         /* the lowest bit options are always accepted */
    1222          12 :         checkparms = setparms & ~MASK_ALWAYS_GOOD;
    1223             : 
    1224          12 :         if (checkparms & BIT_FIX_INIT) {
    1225           0 :                 poptFreeContext(pc);
    1226           0 :                 return fix_users_list();
    1227             :         }
    1228             : 
    1229             :         /* account policy operations */
    1230          12 :         if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) {
    1231             :                 uint32_t value;
    1232           0 :                 enum pdb_policy_type field = account_policy_name_to_typenum(account_policy);
    1233           0 :                 if (field == 0) {
    1234             :                         const char **names;
    1235             :                         int count;
    1236             :                         int i;
    1237           0 :                         account_policy_names_list(talloc_tos(), &names, &count);
    1238           0 :                         fprintf(stderr, "No account policy by that name!\n");
    1239           0 :                         if (count !=0) {
    1240           0 :                                 fprintf(stderr, "Account policy names are:\n");
    1241           0 :                                 for (i = 0; i < count ; i++) {
    1242           0 :                                         d_fprintf(stderr, "%s\n", names[i]);
    1243             :                                 }
    1244             :                         }
    1245           0 :                         TALLOC_FREE(names);
    1246           0 :                         exit(1);
    1247             :                 }
    1248           0 :                 if (!pdb_get_account_policy(field, &value)) {
    1249           0 :                         fprintf(stderr, "valid account policy, but unable to fetch value!\n");
    1250           0 :                         if (!account_policy_value_set)
    1251           0 :                                 exit(1);
    1252             :                 }
    1253           0 :                 printf("account policy \"%s\" description: %s\n", account_policy, account_policy_get_desc(field));
    1254           0 :                 if (account_policy_value_set) {
    1255           0 :                         printf("account policy \"%s\" value was: %u\n", account_policy, value);
    1256           0 :                         if (!pdb_set_account_policy(field, account_policy_value)) {
    1257           0 :                                 fprintf(stderr, "valid account policy, but unable to set value!\n");
    1258           0 :                                 exit(1);
    1259             :                         }
    1260           0 :                         printf("account policy \"%s\" value is now: %lu\n", account_policy, account_policy_value);
    1261           0 :                         exit(0);
    1262             :                 } else {
    1263           0 :                         printf("account policy \"%s\" value is: %u\n", account_policy, value);
    1264           0 :                         exit(0);
    1265             :                 }
    1266             :         }
    1267             : 
    1268          12 :         if (reset_account_policies) {
    1269           0 :                 if (reinit_account_policies()) {
    1270           0 :                         exit(1);
    1271             :                 }
    1272             : 
    1273           0 :                 exit(0);
    1274             :         }
    1275             : 
    1276             :         /* import and export operations */
    1277             : 
    1278          12 :         if (((checkparms & BIT_IMPORT) ||
    1279          12 :              (checkparms & BIT_EXPORT)) &&
    1280           0 :             !(checkparms & ~(BIT_IMPORT +BIT_EXPORT +BIT_USER))) {
    1281             : 
    1282           0 :                 poptFreeContext(pc);
    1283             : 
    1284           0 :                 if (backend_in) {
    1285           0 :                         status = make_pdb_method_name(&bin, backend_in);
    1286             :                 } else {
    1287           0 :                         status = make_pdb_method_name(&bin, backend);
    1288             :                 }
    1289             : 
    1290           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1291           0 :                         fprintf(stderr, "Unable to initialize %s.\n",
    1292           0 :                                 backend_in ? backend_in : backend);
    1293           0 :                         return 1;
    1294             :                 }
    1295             : 
    1296           0 :                 if (backend_out) {
    1297           0 :                         status = make_pdb_method_name(&bout, backend_out);
    1298             :                 } else {
    1299           0 :                         status = make_pdb_method_name(&bout, backend);
    1300             :                 }
    1301             : 
    1302           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1303           0 :                         fprintf(stderr, "Unable to initialize %s.\n",
    1304           0 :                                 backend_out ? backend_out : backend);
    1305           0 :                         return 1;
    1306             :                 }
    1307             : 
    1308           0 :                 if (transfer_account_policies) {
    1309             : 
    1310           0 :                         if (!(checkparms & BIT_USER)) {
    1311           0 :                                 return export_account_policies(bin, bout);
    1312             :                         }
    1313             : 
    1314           0 :                 } else  if (transfer_groups) {
    1315             : 
    1316           0 :                         if (!(checkparms & BIT_USER)) {
    1317           0 :                                 return export_groups(bin, bout);
    1318             :                         }
    1319             : 
    1320             :                 } else {
    1321           0 :                         return export_database(bin, bout,
    1322           0 :                                 (checkparms & BIT_USER) ? user_name : NULL);
    1323             :                 }
    1324             :         }
    1325             : 
    1326             :         /* if BIT_USER is defined but nothing else then threat it as -l -u for compatibility */
    1327             :         /* fake up BIT_LIST if only BIT_USER is defined */
    1328          12 :         if ((checkparms & BIT_USER) && !(checkparms & ~BIT_USER)) {
    1329           0 :                 checkparms += BIT_LIST;
    1330             :         }
    1331             : 
    1332             :         /* modify flag is optional to maintain backwards compatibility */
    1333             :         /* fake up BIT_MODIFY if BIT_USER  and at least one of MASK_USER_GOOD is defined */
    1334          12 :         if (!((checkparms & ~MASK_USER_GOOD) & ~BIT_USER) && (checkparms & MASK_USER_GOOD)) {
    1335           3 :                 checkparms += BIT_MODIFY;
    1336             :         }
    1337             : 
    1338             :         /* list users operations */
    1339          12 :         if (checkparms & BIT_LIST) {
    1340           0 :                 if (!(checkparms & ~BIT_LIST)) {
    1341           0 :                         poptFreeContext(pc);
    1342           0 :                         return print_users_list(verbose, spstyle);
    1343             :                 }
    1344           0 :                 if (!(checkparms & ~(BIT_USER + BIT_LIST))) {
    1345           0 :                         poptFreeContext(pc);
    1346           0 :                         return print_user_info(user_name, verbose, spstyle);
    1347             :                 }
    1348             :         }
    1349             : 
    1350             :         /* mask out users options */
    1351          12 :         checkparms &= ~MASK_USER_GOOD;
    1352             : 
    1353             :         /* if bad password count is reset, we must be modifying */
    1354          12 :         if (checkparms & BIT_BADPWRESET) {
    1355           0 :                 checkparms |= BIT_MODIFY;
    1356           0 :                 checkparms &= ~BIT_BADPWRESET;
    1357             :         }
    1358             : 
    1359             :         /* if logon hours is reset, must modify */
    1360          12 :         if (checkparms & BIT_LOGONHOURS) {
    1361           0 :                 checkparms |= BIT_MODIFY;
    1362           0 :                 checkparms &= ~BIT_LOGONHOURS;
    1363             :         }
    1364             : 
    1365             :         /* account operation */
    1366          12 :         if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) {
    1367             :                 /* check use of -u option */
    1368          12 :                 if (!(checkparms & BIT_USER)) {
    1369           0 :                         fprintf (stderr, "Username not specified! (use -u option)\n");
    1370           0 :                         poptFreeContext(pc);
    1371           0 :                         return -1;
    1372             :                 }
    1373             : 
    1374             :                 /* account creation operations */
    1375          12 :                 if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE))) {
    1376           3 :                         poptFreeContext(pc);
    1377           3 :                         if (checkparms & BIT_MACHINE) {
    1378           0 :                                 return new_machine(user_name, machine_sid);
    1379             :                         } else {
    1380           3 :                                 return new_user(user_name, full_name,
    1381             :                                                 home_dir, home_drive,
    1382             :                                                 logon_script, profile_path,
    1383             :                                                 user_sid, pw_from_stdin);
    1384             :                         }
    1385             :                 }
    1386             : 
    1387             :                 /* account deletion operations */
    1388           9 :                 if (!(checkparms & ~(BIT_DELETE + BIT_USER + BIT_MACHINE))) {
    1389           3 :                         poptFreeContext(pc);
    1390           3 :                         if (checkparms & BIT_MACHINE) {
    1391           0 :                                 return delete_machine_entry(user_name);
    1392             :                         } else {
    1393           3 :                                 return delete_user_entry(user_name);
    1394             :                         }
    1395             :                 }
    1396             : 
    1397             :                 /* account modification operations */
    1398           6 :                 if (!(checkparms & ~(BIT_MODIFY + BIT_USER + BIT_MACHINE))) {
    1399           6 :                         poptFreeContext(pc);
    1400           6 :                         if (checkparms & BIT_MACHINE) {
    1401           0 :                                 return set_machine_info(user_name,
    1402             :                                                         account_control,
    1403             :                                                         machine_sid);
    1404             :                         } else {
    1405           6 :                                 return set_user_info(user_name, full_name,
    1406             :                                                      home_dir, acct_desc,
    1407             :                                                      home_drive, logon_script,
    1408             :                                                      profile_path, account_control,
    1409             :                                                      user_sid, user_domain,
    1410             :                                                      badpw_reset, hours_reset,
    1411             :                                                      kickoff_time, str_hex_pwd);
    1412             :                         }
    1413             :                 }
    1414             :         }
    1415             : 
    1416           0 :         if (setparms >= 0x20) {
    1417           0 :                 fprintf (stderr, "Incompatible or insufficient options on command line!\n");
    1418             :         }
    1419           0 :         poptPrintHelp(pc, stderr, 0);
    1420             : 
    1421           0 :         gfree_all();
    1422           0 :         poptFreeContext(pc);
    1423           0 :         TALLOC_FREE(frame);
    1424           0 :         return 1;
    1425             : }

Generated by: LCOV version 1.14