~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/utils/pdbedit.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
   Unix SMB/CIFS implementation.
3
 
   passdb editing frontend
4
 
   
5
 
   Copyright (C) Simo Sorce      2000
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 2 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, write to the Free Software
21
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
 
*/
23
 
 
24
 
#include "includes.h"
25
 
 
26
 
#define BIT_BACKEND     0x00000004
27
 
#define BIT_VERBOSE     0x00000008
28
 
#define BIT_SPSTYLE     0x00000010
29
 
#define BIT_CAN_CHANGE  0x00000020
30
 
#define BIT_MUST_CHANGE 0x00000040
31
 
#define BIT_USERSIDS    0x00000080
32
 
#define BIT_FULLNAME    0x00000100
33
 
#define BIT_HOMEDIR     0x00000200
34
 
#define BIT_HDIRDRIVE   0x00000400
35
 
#define BIT_LOGSCRIPT   0x00000800
36
 
#define BIT_PROFILE     0x00001000
37
 
#define BIT_MACHINE     0x00002000
38
 
#define BIT_USERDOMAIN  0x00004000
39
 
#define BIT_USER        0x00008000
40
 
#define BIT_LIST        0x00010000
41
 
#define BIT_MODIFY      0x00020000
42
 
#define BIT_CREATE      0x00040000
43
 
#define BIT_DELETE      0x00080000
44
 
#define BIT_ACCPOLICY   0x00100000
45
 
#define BIT_ACCPOLVAL   0x00200000
46
 
#define BIT_ACCTCTRL    0x00400000
47
 
#define BIT_RESERV_7    0x00800000
48
 
#define BIT_IMPORT      0x01000000
49
 
#define BIT_EXPORT      0x02000000
50
 
#define BIT_FIX_INIT    0x04000000
51
 
#define BIT_BADPWRESET  0x08000000
52
 
#define BIT_LOGONHOURS  0x10000000
53
 
 
54
 
#define MASK_ALWAYS_GOOD        0x0000001F
55
 
#define MASK_USER_GOOD          0x00405FE0
56
 
 
57
 
/*********************************************************
58
 
 Add all currently available users to another db
59
 
 ********************************************************/
60
 
 
61
 
static int export_database (struct pdb_methods *in, 
62
 
                            struct pdb_methods *out, 
63
 
                            const char *username) 
64
 
{
65
 
        struct samu *user = NULL;
66
 
        NTSTATUS status;
67
 
 
68
 
        DEBUG(3, ("export_database: username=\"%s\"\n", username ? username : "(NULL)"));
69
 
 
70
 
        status = in->setsampwent(in, 0, 0);
71
 
        if ( NT_STATUS_IS_ERR(status) ) {
72
 
                fprintf(stderr, "Unable to set account database iterator for %s!\n", 
73
 
                        in->name);
74
 
                return 1;
75
 
        }
76
 
 
77
 
        if ( ( user = samu_new( NULL ) ) == NULL ) {
78
 
                fprintf(stderr, "export_database: Memory allocation failure!\n");
79
 
                return 1;
80
 
        }
81
 
 
82
 
        while ( NT_STATUS_IS_OK(in->getsampwent(in, user)) ) 
83
 
        {
84
 
                DEBUG(4, ("Processing account %s\n", user->username));
85
 
 
86
 
                /* If we don't have a specific user or if we do and 
87
 
                   the login name matches */
88
 
 
89
 
                if ( !username || (strcmp(username, user->username) == 0)) {
90
 
                        struct samu *account;
91
 
 
92
 
                        if ( (account = samu_new( NULL )) == NULL ) {
93
 
                                fprintf(stderr, "export_database: Memory allocation failure!\n");
94
 
                                TALLOC_FREE( user );
95
 
                                in->endsampwent( in );
96
 
                                return 1;
97
 
                        }
98
 
 
99
 
                        printf("Importing accout for %s...", user->username);
100
 
                        if ( !NT_STATUS_IS_OK(out->getsampwnam( out, account, user->username )) ) {
101
 
                                status = out->add_sam_account(out, user);
102
 
                        } else {
103
 
                                status = out->update_sam_account( out, user );
104
 
                        }
105
 
 
106
 
                        if ( NT_STATUS_IS_OK(status) ) {
107
 
                                printf( "ok\n");
108
 
                        } else {
109
 
                                printf( "failed\n");
110
 
                        }
111
 
 
112
 
                        TALLOC_FREE( account );
113
 
                }
114
 
 
115
 
                /* clean up and get ready for another run */
116
 
 
117
 
                TALLOC_FREE( user );
118
 
 
119
 
                if ( ( user = samu_new( NULL ) ) == NULL ) {
120
 
                        fprintf(stderr, "export_database: Memory allocation failure!\n");
121
 
                        return 1;
122
 
                }
123
 
        }
124
 
 
125
 
        TALLOC_FREE( user );
126
 
 
127
 
        in->endsampwent(in);
128
 
 
129
 
        return 0;
130
 
}
131
 
 
132
 
/*********************************************************
133
 
 Add all currently available group mappings to another db
134
 
 ********************************************************/
135
 
 
136
 
static int export_groups (struct pdb_methods *in, struct pdb_methods *out) 
137
 
{
138
 
        GROUP_MAP *maps = NULL;
139
 
        size_t i, entries = 0;
140
 
        NTSTATUS status;
141
 
 
142
 
        status = in->enum_group_mapping(in, get_global_sam_sid(), 
143
 
                        SID_NAME_DOM_GRP, &maps, &entries, False);
144
 
 
145
 
        if ( NT_STATUS_IS_ERR(status) ) {
146
 
                fprintf(stderr, "Unable to enumerate group map entries.\n");
147
 
                return 1;
148
 
        }
149
 
 
150
 
        for (i=0; i<entries; i++) {
151
 
                out->add_group_mapping_entry(out, &(maps[i]));
152
 
        }
153
 
 
154
 
        SAFE_FREE( maps );
155
 
 
156
 
        return 0;
157
 
}
158
 
 
159
 
/*********************************************************
160
 
 Reset account policies to their default values and remove marker
161
 
 ********************************************************/
162
 
 
163
 
static int reinit_account_policies (void) 
164
 
{
165
 
        int i;
166
 
 
167
 
        for (i=1; decode_account_policy_name(i) != NULL; i++) {
168
 
                uint32 policy_value;
169
 
                if (!account_policy_get_default(i, &policy_value)) {
170
 
                        fprintf(stderr, "Can't get default account policy\n");
171
 
                        return -1;
172
 
                }
173
 
                if (!account_policy_set(i, policy_value)) {
174
 
                        fprintf(stderr, "Can't set account policy in tdb\n");
175
 
                        return -1;
176
 
                }
177
 
        }
178
 
 
179
 
        if (!remove_account_policy_migrated()) {
180
 
                fprintf(stderr, "Can't remove marker from tdb\n");
181
 
                return -1;
182
 
        }
183
 
 
184
 
        return 0;
185
 
}
186
 
 
187
 
 
188
 
/*********************************************************
189
 
 Add all currently available account policy from tdb to one backend
190
 
 ********************************************************/
191
 
 
192
 
static int export_account_policies (struct pdb_methods *in, struct pdb_methods *out) 
193
 
{
194
 
        int i;
195
 
 
196
 
        if (!account_policy_migrated(True)) {
197
 
                fprintf(stderr, "Unable to set account policy marker in tdb\n");
198
 
                return -1;
199
 
        }
200
 
 
201
 
        for ( i=1; decode_account_policy_name(i) != NULL; i++ ) {
202
 
                uint32 policy_value;
203
 
                NTSTATUS status;
204
 
 
205
 
                status = in->get_account_policy(in, i, &policy_value);
206
 
 
207
 
                if ( NT_STATUS_IS_ERR(status) ) {
208
 
                        fprintf(stderr, "Unable to get account policy from %s\n", in->name);
209
 
                        remove_account_policy_migrated();
210
 
                        return -1;
211
 
                }
212
 
 
213
 
                status = out->set_account_policy(out, i, policy_value);
214
 
 
215
 
                if ( NT_STATUS_IS_ERR(status) ) {
216
 
                        fprintf(stderr, "Unable to migrate account policy to %s\n", out->name);
217
 
                        remove_account_policy_migrated();
218
 
                        return -1;
219
 
                }
220
 
        }
221
 
 
222
 
        return 0;
223
 
}
224
 
 
225
 
 
226
 
/*********************************************************
227
 
 Print info from sam structure
228
 
**********************************************************/
229
 
 
230
 
static int print_sam_info (struct samu *sam_pwent, BOOL verbosity, BOOL smbpwdstyle)
231
 
{
232
 
        uid_t uid;
233
 
        time_t tmp;
234
 
 
235
 
        /* TODO: chaeck if entry is a user or a workstation */
236
 
        if (!sam_pwent) return -1;
237
 
        
238
 
        if (verbosity) {
239
 
                pstring temp;
240
 
                const uint8 *hours;
241
 
                
242
 
                printf ("Unix username:        %s\n", pdb_get_username(sam_pwent));
243
 
                printf ("NT username:          %s\n", pdb_get_nt_username(sam_pwent));
244
 
                printf ("Account Flags:        %s\n", pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent), NEW_PW_FORMAT_SPACE_PADDED_LEN));
245
 
                printf ("User SID:             %s\n",
246
 
                        sid_string_static(pdb_get_user_sid(sam_pwent)));
247
 
                printf ("Primary Group SID:    %s\n",
248
 
                        sid_string_static(pdb_get_group_sid(sam_pwent)));
249
 
                printf ("Full Name:            %s\n", pdb_get_fullname(sam_pwent));
250
 
                printf ("Home Directory:       %s\n", pdb_get_homedir(sam_pwent));
251
 
                printf ("HomeDir Drive:        %s\n", pdb_get_dir_drive(sam_pwent));
252
 
                printf ("Logon Script:         %s\n", pdb_get_logon_script(sam_pwent));
253
 
                printf ("Profile Path:         %s\n", pdb_get_profile_path(sam_pwent));
254
 
                printf ("Domain:               %s\n", pdb_get_domain(sam_pwent));
255
 
                printf ("Account desc:         %s\n", pdb_get_acct_desc(sam_pwent));
256
 
                printf ("Workstations:         %s\n", pdb_get_workstations(sam_pwent));
257
 
                printf ("Munged dial:          %s\n", pdb_get_munged_dial(sam_pwent));
258
 
                
259
 
                tmp = pdb_get_logon_time(sam_pwent);
260
 
                printf ("Logon time:           %s\n", tmp ? http_timestring(tmp) : "0");
261
 
                
262
 
                tmp = pdb_get_logoff_time(sam_pwent);
263
 
                printf ("Logoff time:          %s\n", tmp ? http_timestring(tmp) : "0");
264
 
                
265
 
                tmp = pdb_get_kickoff_time(sam_pwent);
266
 
                printf ("Kickoff time:         %s\n", tmp ? http_timestring(tmp) : "0");
267
 
                
268
 
                tmp = pdb_get_pass_last_set_time(sam_pwent);
269
 
                printf ("Password last set:    %s\n", tmp ? http_timestring(tmp) : "0");
270
 
                
271
 
                tmp = pdb_get_pass_can_change_time(sam_pwent);
272
 
                printf ("Password can change:  %s\n", tmp ? http_timestring(tmp) : "0");
273
 
                
274
 
                tmp = pdb_get_pass_must_change_time(sam_pwent);
275
 
                printf ("Password must change: %s\n", tmp ? http_timestring(tmp) : "0");
276
 
 
277
 
                tmp = pdb_get_bad_password_time(sam_pwent);
278
 
                printf ("Last bad password   : %s\n", tmp ? http_timestring(tmp) : "0");
279
 
                printf ("Bad password count  : %d\n", 
280
 
                        pdb_get_bad_password_count(sam_pwent));
281
 
                
282
 
                hours = pdb_get_hours(sam_pwent);
283
 
                pdb_sethexhours(temp, hours);
284
 
                printf ("Logon hours         : %s\n", temp);
285
 
                
286
 
        } else if (smbpwdstyle) {
287
 
                char lm_passwd[33];
288
 
                char nt_passwd[33];
289
 
 
290
 
                uid = nametouid(pdb_get_username(sam_pwent));
291
 
                pdb_sethexpwd(lm_passwd, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
292
 
                pdb_sethexpwd(nt_passwd, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
293
 
                        
294
 
                printf("%s:%lu:%s:%s:%s:LCT-%08X:\n",
295
 
                       pdb_get_username(sam_pwent),
296
 
                       (unsigned long)uid,
297
 
                       lm_passwd,
298
 
                       nt_passwd,
299
 
                       pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent),NEW_PW_FORMAT_SPACE_PADDED_LEN),
300
 
                       (uint32)pdb_get_pass_last_set_time(sam_pwent));
301
 
        } else {
302
 
                uid = nametouid(pdb_get_username(sam_pwent));
303
 
                printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid, 
304
 
                        pdb_get_fullname(sam_pwent));
305
 
        }
306
 
 
307
 
        return 0;       
308
 
}
309
 
 
310
 
/*********************************************************
311
 
 Get an Print User Info
312
 
**********************************************************/
313
 
 
314
 
static int print_user_info (struct pdb_methods *in, const char *username, BOOL verbosity, BOOL smbpwdstyle)
315
 
{
316
 
        struct samu *sam_pwent=NULL;
317
 
        BOOL ret;
318
 
 
319
 
        if ( (sam_pwent = samu_new( NULL )) == NULL ) {
320
 
                return -1;
321
 
        }
322
 
 
323
 
        ret = NT_STATUS_IS_OK(in->getsampwnam (in, sam_pwent, username));
324
 
 
325
 
        if (ret==False) {
326
 
                fprintf (stderr, "Username not found!\n");
327
 
                TALLOC_FREE(sam_pwent);
328
 
                return -1;
329
 
        }
330
 
 
331
 
        ret=print_sam_info (sam_pwent, verbosity, smbpwdstyle);
332
 
        TALLOC_FREE(sam_pwent);
333
 
        
334
 
        return ret;
335
 
}
336
 
        
337
 
/*********************************************************
338
 
 List Users
339
 
**********************************************************/
340
 
static int print_users_list (struct pdb_methods *in, BOOL verbosity, BOOL smbpwdstyle)
341
 
{
342
 
        struct samu *sam_pwent=NULL;
343
 
        BOOL check;
344
 
        
345
 
        check = NT_STATUS_IS_OK(in->setsampwent(in, False, 0));
346
 
        if (!check) {
347
 
                return 1;
348
 
        }
349
 
 
350
 
        check = True;
351
 
        if ( (sam_pwent = samu_new( NULL )) == NULL ) {
352
 
                return 1;
353
 
        }
354
 
 
355
 
        while (check && NT_STATUS_IS_OK(in->getsampwent (in, sam_pwent))) {
356
 
                if (verbosity)
357
 
                        printf ("---------------\n");
358
 
                print_sam_info (sam_pwent, verbosity, smbpwdstyle);
359
 
                TALLOC_FREE(sam_pwent);
360
 
                
361
 
                if ( (sam_pwent = samu_new( NULL )) == NULL ) {
362
 
                        check = False;
363
 
                }
364
 
        }
365
 
        if (check) 
366
 
                TALLOC_FREE(sam_pwent);
367
 
        
368
 
        in->endsampwent(in);
369
 
        return 0;
370
 
}
371
 
 
372
 
/*********************************************************
373
 
 Fix a list of Users for uninitialised passwords
374
 
**********************************************************/
375
 
static int fix_users_list (struct pdb_methods *in)
376
 
{
377
 
        struct samu *sam_pwent=NULL;
378
 
        BOOL check;
379
 
        
380
 
        check = NT_STATUS_IS_OK(in->setsampwent(in, False, 0));
381
 
        if (!check) {
382
 
                return 1;
383
 
        }
384
 
 
385
 
        check = True;
386
 
        if ( (sam_pwent = samu_new( NULL )) == NULL ) {
387
 
                return 1;
388
 
        }
389
 
 
390
 
        while (check && NT_STATUS_IS_OK(in->getsampwent (in, sam_pwent))) {
391
 
                printf("Updating record for user %s\n", pdb_get_username(sam_pwent));
392
 
        
393
 
                if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
394
 
                        printf("Update of user %s failed!\n", pdb_get_username(sam_pwent));
395
 
                }
396
 
                TALLOC_FREE(sam_pwent);
397
 
                if ( (sam_pwent = samu_new( NULL )) == NULL ) {
398
 
                        check = False;
399
 
                }
400
 
                if (!check) {
401
 
                        fprintf(stderr, "Failed to initialise new struct samu structure (out of memory?)\n");
402
 
                }
403
 
                        
404
 
        }
405
 
        if (check) 
406
 
                TALLOC_FREE(sam_pwent);
407
 
        
408
 
        in->endsampwent(in);
409
 
        return 0;
410
 
}
411
 
 
412
 
/*********************************************************
413
 
 Set User Info
414
 
**********************************************************/
415
 
 
416
 
static int set_user_info (struct pdb_methods *in, const char *username, 
417
 
                          const char *fullname, const char *homedir, 
418
 
                          const char *acct_desc, 
419
 
                          const char *drive, const char *script, 
420
 
                          const char *profile, const char *account_control,
421
 
                          const char *user_sid, const char *user_domain,
422
 
                          const BOOL badpw, const BOOL hours,
423
 
                          time_t pwd_can_change, time_t pwd_must_change)
424
 
{
425
 
        BOOL updated_autolock = False, updated_badpw = False;
426
 
        struct samu *sam_pwent=NULL;
427
 
        BOOL ret;
428
 
        
429
 
        if ( (sam_pwent = samu_new( NULL )) == NULL ) {
430
 
                return 1;
431
 
        }
432
 
        
433
 
        ret = NT_STATUS_IS_OK(in->getsampwnam (in, sam_pwent, username));
434
 
        if (ret==False) {
435
 
                fprintf (stderr, "Username not found!\n");
436
 
                TALLOC_FREE(sam_pwent);
437
 
                return -1;
438
 
        }
439
 
 
440
 
        if (hours) {
441
 
                uint8 hours_array[MAX_HOURS_LEN];
442
 
                uint32 hours_len;
443
 
                
444
 
                hours_len = pdb_get_hours_len(sam_pwent);
445
 
                memset(hours_array, 0xff, hours_len);
446
 
                
447
 
                pdb_set_hours(sam_pwent, hours_array, PDB_CHANGED);
448
 
        }
449
 
 
450
 
        if (pwd_can_change != -1) {
451
 
                pdb_set_pass_can_change_time(sam_pwent, pwd_can_change, PDB_CHANGED);
452
 
        }
453
 
 
454
 
        if (pwd_must_change != -1) {
455
 
                pdb_set_pass_must_change_time(sam_pwent, pwd_must_change, PDB_CHANGED);
456
 
        }
457
 
 
458
 
        if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) {
459
 
                DEBUG(2,("pdb_update_autolock_flag failed.\n"));
460
 
        }
461
 
 
462
 
        if (!pdb_update_bad_password_count(sam_pwent, &updated_badpw)) {
463
 
                DEBUG(2,("pdb_update_bad_password_count failed.\n"));
464
 
        }
465
 
 
466
 
        if (fullname)
467
 
                pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
468
 
        if (acct_desc)
469
 
                pdb_set_acct_desc(sam_pwent, acct_desc, PDB_CHANGED);
470
 
        if (homedir)
471
 
                pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
472
 
        if (drive)
473
 
                pdb_set_dir_drive(sam_pwent,drive, PDB_CHANGED);
474
 
        if (script)
475
 
                pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
476
 
        if (profile)
477
 
                pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED);
478
 
        if (user_domain)
479
 
                pdb_set_domain(sam_pwent, user_domain, PDB_CHANGED);
480
 
 
481
 
        if (account_control) {
482
 
                uint32 not_settable = ~(ACB_DISABLED|ACB_HOMDIRREQ|ACB_PWNOTREQ|
483
 
                                        ACB_PWNOEXP|ACB_AUTOLOCK);
484
 
 
485
 
                uint32 newflag = pdb_decode_acct_ctrl(account_control);
486
 
 
487
 
                if (newflag & not_settable) {
488
 
                        fprintf(stderr, "Can only set [NDHLX] flags\n");
489
 
                        TALLOC_FREE(sam_pwent);
490
 
                        return -1;
491
 
                }
492
 
 
493
 
                pdb_set_acct_ctrl(sam_pwent,
494
 
                                  (pdb_get_acct_ctrl(sam_pwent) & not_settable) | newflag,
495
 
                                  PDB_CHANGED);
496
 
        }
497
 
        if (user_sid) {
498
 
                DOM_SID u_sid;
499
 
                if (!string_to_sid(&u_sid, user_sid)) {
500
 
                        /* not a complete sid, may be a RID, try building a SID */
501
 
                        int u_rid;
502
 
                        
503
 
                        if (sscanf(user_sid, "%d", &u_rid) != 1) {
504
 
                                fprintf(stderr, "Error passed string is not a complete user SID or RID!\n");
505
 
                                return -1;
506
 
                        }
507
 
                        sid_copy(&u_sid, get_global_sam_sid());
508
 
                        sid_append_rid(&u_sid, u_rid);
509
 
                }
510
 
                pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED);
511
 
        }
512
 
 
513
 
        if (badpw) {
514
 
                pdb_set_bad_password_count(sam_pwent, 0, PDB_CHANGED);
515
 
                pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED);
516
 
        }
517
 
 
518
 
        if (NT_STATUS_IS_OK(in->update_sam_account (in, sam_pwent)))
519
 
                print_user_info (in, username, True, False);
520
 
        else {
521
 
                fprintf (stderr, "Unable to modify entry!\n");
522
 
                TALLOC_FREE(sam_pwent);
523
 
                return -1;
524
 
        }
525
 
        TALLOC_FREE(sam_pwent);
526
 
        return 0;
527
 
}
528
 
 
529
 
/*********************************************************
530
 
 Add New User
531
 
**********************************************************/
532
 
static int new_user (struct pdb_methods *in, const char *username,
533
 
                        const char *fullname, const char *homedir,
534
 
                        const char *drive, const char *script,
535
 
                        const char *profile, char *user_sid, BOOL stdin_get)
536
 
{
537
 
        struct samu *sam_pwent;
538
 
        char *password1, *password2;
539
 
        int rc_pwd_cmp;
540
 
        struct passwd *pwd;
541
 
 
542
 
        get_global_sam_sid();
543
 
 
544
 
        if ( !(pwd = getpwnam_alloc( NULL, username )) ) {
545
 
                DEBUG(0,("Cannot locate Unix account for %s\n", username));
546
 
                return -1;
547
 
        }
548
 
 
549
 
        if ( (sam_pwent = samu_new( NULL )) == NULL ) {
550
 
                DEBUG(0, ("Memory allocation failure!\n"));
551
 
                return -1;
552
 
        }
553
 
 
554
 
        if (!NT_STATUS_IS_OK(samu_alloc_rid_unix(sam_pwent, pwd ))) {
555
 
                TALLOC_FREE( sam_pwent );
556
 
                TALLOC_FREE( pwd );
557
 
                DEBUG(0, ("could not create account to add new user %s\n", username));
558
 
                return -1;
559
 
        }
560
 
 
561
 
        password1 = get_pass( "new password:", stdin_get);
562
 
        password2 = get_pass( "retype new password:", stdin_get);
563
 
        if ((rc_pwd_cmp = strcmp (password1, password2))) {
564
 
                fprintf (stderr, "Passwords do not match!\n");
565
 
                TALLOC_FREE(sam_pwent);
566
 
        } else {
567
 
                pdb_set_plaintext_passwd(sam_pwent, password1);
568
 
        }
569
 
 
570
 
        memset(password1, 0, strlen(password1));
571
 
        SAFE_FREE(password1);
572
 
        memset(password2, 0, strlen(password2));
573
 
        SAFE_FREE(password2);
574
 
 
575
 
        /* pwds do _not_ match? */
576
 
        if (rc_pwd_cmp)
577
 
                return -1;
578
 
 
579
 
        if (fullname)
580
 
                pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
581
 
        if (homedir)
582
 
                pdb_set_homedir (sam_pwent, homedir, PDB_CHANGED);
583
 
        if (drive)
584
 
                pdb_set_dir_drive (sam_pwent, drive, PDB_CHANGED);
585
 
        if (script)
586
 
                pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
587
 
        if (profile)
588
 
                pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED);
589
 
        if (user_sid) {
590
 
                DOM_SID u_sid;
591
 
                if (!string_to_sid(&u_sid, user_sid)) {
592
 
                        /* not a complete sid, may be a RID, try building a SID */
593
 
                        int u_rid;
594
 
                        
595
 
                        if (sscanf(user_sid, "%d", &u_rid) != 1) {
596
 
                                fprintf(stderr, "Error passed string is not a complete user SID or RID!\n");
597
 
                                return -1;
598
 
                        }
599
 
                        sid_copy(&u_sid, get_global_sam_sid());
600
 
                        sid_append_rid(&u_sid, u_rid);
601
 
                }
602
 
                pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED);
603
 
        }
604
 
        
605
 
        pdb_set_acct_ctrl (sam_pwent, ACB_NORMAL, PDB_CHANGED);
606
 
        
607
 
        if (NT_STATUS_IS_OK(in->add_sam_account (in, sam_pwent))) { 
608
 
                print_user_info (in, username, True, False);
609
 
        } else {
610
 
                fprintf (stderr, "Unable to add user! (does it already exist?)\n");
611
 
                TALLOC_FREE(sam_pwent);
612
 
                return -1;
613
 
        }
614
 
        TALLOC_FREE(sam_pwent);
615
 
        return 0;
616
 
}
617
 
 
618
 
/*********************************************************
619
 
 Add New Machine
620
 
**********************************************************/
621
 
 
622
 
static int new_machine (struct pdb_methods *in, const char *machine_in)
623
 
{
624
 
        struct samu *sam_pwent=NULL;
625
 
        fstring machinename;
626
 
        fstring machineaccount;
627
 
        struct passwd  *pwd = NULL;
628
 
        
629
 
        get_global_sam_sid();
630
 
 
631
 
        if (strlen(machine_in) == 0) {
632
 
                fprintf(stderr, "No machine name given\n");
633
 
                return -1;
634
 
        }
635
 
 
636
 
        fstrcpy(machinename, machine_in); 
637
 
        machinename[15]= '\0';
638
 
 
639
 
        if (machinename[strlen (machinename) -1] == '$')
640
 
                machinename[strlen (machinename) -1] = '\0';
641
 
        
642
 
        strlower_m(machinename);
643
 
        
644
 
        fstrcpy(machineaccount, machinename);
645
 
        fstrcat(machineaccount, "$");
646
 
 
647
 
        if ((pwd = getpwnam_alloc(NULL, machineaccount))) {
648
 
 
649
 
                if ( (sam_pwent = samu_new( NULL )) == NULL ) {
650
 
                        fprintf(stderr, "Memory allocation error!\n");
651
 
                        TALLOC_FREE(pwd);
652
 
                        return -1;
653
 
                }
654
 
 
655
 
                if ( !NT_STATUS_IS_OK(samu_set_unix(sam_pwent, pwd )) ) {
656
 
                        fprintf(stderr, "Could not init sam from pw\n");
657
 
                        TALLOC_FREE(pwd);
658
 
                        return -1;
659
 
                }
660
 
 
661
 
                TALLOC_FREE(pwd);
662
 
        } else {
663
 
                if ( (sam_pwent = samu_new( NULL )) == NULL ) {
664
 
                        fprintf(stderr, "Could not init sam from pw\n");
665
 
                        return -1;
666
 
                }
667
 
        }
668
 
 
669
 
        pdb_set_plaintext_passwd (sam_pwent, machinename);
670
 
        pdb_set_username (sam_pwent, machineaccount, PDB_CHANGED);      
671
 
        pdb_set_acct_ctrl (sam_pwent, ACB_WSTRUST, PDB_CHANGED);
672
 
        
673
 
        if (NT_STATUS_IS_OK(in->add_sam_account (in, sam_pwent))) {
674
 
                print_user_info (in, machineaccount, True, False);
675
 
        } else {
676
 
                fprintf (stderr, "Unable to add machine! (does it already exist?)\n");
677
 
                TALLOC_FREE(sam_pwent);
678
 
                return -1;
679
 
        }
680
 
        TALLOC_FREE(sam_pwent);
681
 
        return 0;
682
 
}
683
 
 
684
 
/*********************************************************
685
 
 Delete user entry
686
 
**********************************************************/
687
 
 
688
 
static int delete_user_entry (struct pdb_methods *in, const char *username)
689
 
{
690
 
        struct samu *samaccount = NULL;
691
 
 
692
 
        if ( (samaccount = samu_new( NULL )) == NULL ) {
693
 
                return -1;
694
 
        }
695
 
 
696
 
        if (!NT_STATUS_IS_OK(in->getsampwnam(in, samaccount, username))) {
697
 
                fprintf (stderr, "user %s does not exist in the passdb\n", username);
698
 
                return -1;
699
 
        }
700
 
 
701
 
        if (!NT_STATUS_IS_OK(in->delete_sam_account (in, samaccount))) {
702
 
                fprintf (stderr, "Unable to delete user %s\n", username);
703
 
                return -1;
704
 
        }
705
 
        return 0;
706
 
}
707
 
 
708
 
/*********************************************************
709
 
 Delete machine entry
710
 
**********************************************************/
711
 
 
712
 
static int delete_machine_entry (struct pdb_methods *in, const char *machinename)
713
 
{
714
 
        fstring name;
715
 
        struct samu *samaccount = NULL;
716
 
 
717
 
        if (strlen(machinename) == 0) {
718
 
                fprintf(stderr, "No machine name given\n");
719
 
                return -1;
720
 
        }
721
 
        
722
 
        fstrcpy(name, machinename);
723
 
        name[15] = '\0';
724
 
        if (name[strlen(name)-1] != '$')
725
 
                fstrcat (name, "$");
726
 
 
727
 
        if ( (samaccount = samu_new( NULL )) == NULL ) {
728
 
                return -1;
729
 
        }
730
 
 
731
 
        if (!NT_STATUS_IS_OK(in->getsampwnam(in, samaccount, name))) {
732
 
                fprintf (stderr, "machine %s does not exist in the passdb\n", name);
733
 
                return -1;
734
 
        }
735
 
 
736
 
        if (!NT_STATUS_IS_OK(in->delete_sam_account (in, samaccount))) {
737
 
                fprintf (stderr, "Unable to delete machine %s\n", name);
738
 
                return -1;
739
 
        }
740
 
 
741
 
        return 0;
742
 
}
743
 
 
744
 
/*********************************************************
745
 
 Start here.
746
 
**********************************************************/
747
 
 
748
 
int main (int argc, char **argv)
749
 
{
750
 
        static BOOL list_users = False;
751
 
        static BOOL verbose = False;
752
 
        static BOOL spstyle = False;
753
 
        static BOOL machine = False;
754
 
        static BOOL add_user = False;
755
 
        static BOOL delete_user = False;
756
 
        static BOOL modify_user = False;
757
 
        uint32  setparms, checkparms;
758
 
        int opt;
759
 
        static char *full_name = NULL;
760
 
        static char *acct_desc = NULL;
761
 
        static const char *user_name = NULL;
762
 
        static char *home_dir = NULL;
763
 
        static char *home_drive = NULL;
764
 
        static char *backend = NULL;
765
 
        static char *backend_in = NULL;
766
 
        static char *backend_out = NULL;
767
 
        static BOOL transfer_groups = False;
768
 
        static BOOL transfer_account_policies = False;
769
 
        static BOOL reset_account_policies = False;
770
 
        static BOOL  force_initialised_password = False;
771
 
        static char *logon_script = NULL;
772
 
        static char *profile_path = NULL;
773
 
        static char *user_domain = NULL;
774
 
        static char *account_control = NULL;
775
 
        static char *account_policy = NULL;
776
 
        static char *user_sid = NULL;
777
 
        static long int account_policy_value = 0;
778
 
        BOOL account_policy_value_set = False;
779
 
        static BOOL badpw_reset = False;
780
 
        static BOOL hours_reset = False;
781
 
        static char *pwd_can_change_time = NULL;
782
 
        static char *pwd_must_change_time = NULL;
783
 
        static char *pwd_time_format = NULL;
784
 
        static BOOL pw_from_stdin = False;
785
 
        struct pdb_methods *bin, *bout, *bdef;
786
 
        poptContext pc;
787
 
        struct poptOption long_options[] = {
788
 
                POPT_AUTOHELP
789
 
                {"list",        'L', POPT_ARG_NONE, &list_users, 0, "list all users", NULL},
790
 
                {"verbose",     'v', POPT_ARG_NONE, &verbose, 0, "be verbose", NULL },
791
 
                {"smbpasswd-style",     'w',POPT_ARG_NONE, &spstyle, 0, "give output in smbpasswd style", NULL},
792
 
                {"user",        'u', POPT_ARG_STRING, &user_name, 0, "use username", "USER" },
793
 
                {"account-desc",        'N', POPT_ARG_STRING, &acct_desc, 0, "set account description", NULL},
794
 
                {"fullname",    'f', POPT_ARG_STRING, &full_name, 0, "set full name", NULL},
795
 
                {"homedir",     'h', POPT_ARG_STRING, &home_dir, 0, "set home directory", NULL},
796
 
                {"drive",       'D', POPT_ARG_STRING, &home_drive, 0, "set home drive", NULL},
797
 
                {"script",      'S', POPT_ARG_STRING, &logon_script, 0, "set logon script", NULL},
798
 
                {"profile",     'p', POPT_ARG_STRING, &profile_path, 0, "set profile path", NULL},
799
 
                {"domain",      'I', POPT_ARG_STRING, &user_domain, 0, "set a users' domain", NULL},
800
 
                {"user SID",    'U', POPT_ARG_STRING, &user_sid, 0, "set user SID or RID", NULL},
801
 
                {"create",      'a', POPT_ARG_NONE, &add_user, 0, "create user", NULL},
802
 
                {"modify",      'r', POPT_ARG_NONE, &modify_user, 0, "modify user", NULL},
803
 
                {"machine",     'm', POPT_ARG_NONE, &machine, 0, "account is a machine account", NULL},
804
 
                {"delete",      'x', POPT_ARG_NONE, &delete_user, 0, "delete user", NULL},
805
 
                {"backend",     'b', POPT_ARG_STRING, &backend, 0, "use different passdb backend as default backend", NULL},
806
 
                {"import",      'i', POPT_ARG_STRING, &backend_in, 0, "import user accounts from this backend", NULL},
807
 
                {"export",      'e', POPT_ARG_STRING, &backend_out, 0, "export user accounts to this backend", NULL},
808
 
                {"group",       'g', POPT_ARG_NONE, &transfer_groups, 0, "use -i and -e for groups", NULL},
809
 
                {"policies",    'y', POPT_ARG_NONE, &transfer_account_policies, 0, "use -i and -e to move account policies between backends", NULL},
810
 
                {"policies-reset",      0, POPT_ARG_NONE, &reset_account_policies, 0, "restore default policies", NULL},
811
 
                {"account-policy",      'P', POPT_ARG_STRING, &account_policy, 0,"value of an account policy (like maximum password age)",NULL},
812
 
                {"value",       'C', POPT_ARG_LONG, &account_policy_value, 'C',"set the account policy to this value", NULL},
813
 
                {"account-control",     'c', POPT_ARG_STRING, &account_control, 0, "Values of account control", NULL},
814
 
                {"force-initialized-passwords", 0, POPT_ARG_NONE, &force_initialised_password, 0, "Force initialization of corrupt password strings in a passdb backend", NULL},
815
 
                {"bad-password-count-reset", 'z', POPT_ARG_NONE, &badpw_reset, 0, "reset bad password count", NULL},
816
 
                {"logon-hours-reset", 'Z', POPT_ARG_NONE, &hours_reset, 0, "reset logon hours", NULL},
817
 
                {"pwd-can-change-time", 0, POPT_ARG_STRING, &pwd_can_change_time, 0, "Set password can change time (unix time in seconds since 1970 if time format not provided)", NULL },
818
 
                {"pwd-must-change-time", 0, POPT_ARG_STRING, &pwd_must_change_time, 0, "Set password must change time (unix time in seconds since 1970 if time format not provided)", NULL },
819
 
                {"time-format", 0, POPT_ARG_STRING, &pwd_time_format, 0, "The time format for time parameters", NULL },
820
 
                {"password-from-stdin", 't', POPT_ARG_NONE, &pw_from_stdin, 0, "get password from standard in", NULL},
821
 
                POPT_COMMON_SAMBA
822
 
                POPT_TABLEEND
823
 
        };
824
 
        
825
 
        bin = bout = bdef = NULL;
826
 
 
827
 
        load_case_tables();
828
 
 
829
 
        setup_logging("pdbedit", True);
830
 
        
831
 
        pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
832
 
                            POPT_CONTEXT_KEEP_FIRST);
833
 
        
834
 
        while((opt = poptGetNextOpt(pc)) != -1) {
835
 
                switch (opt) {
836
 
                case 'C':
837
 
                        account_policy_value_set = True;
838
 
                        break;
839
 
                }
840
 
        }
841
 
 
842
 
        poptGetArg(pc); /* Drop argv[0], the program name */
843
 
 
844
 
        if (user_name == NULL)
845
 
                user_name = poptGetArg(pc);
846
 
 
847
 
        if (!lp_load(dyn_CONFIGFILE,True,False,False,True)) {
848
 
                fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
849
 
                exit(1);
850
 
        }
851
 
 
852
 
        if(!initialize_password_db(False))
853
 
                exit(1);
854
 
 
855
 
        if (!init_names())
856
 
                exit(1);
857
 
 
858
 
        setparms =      (backend ? BIT_BACKEND : 0) +
859
 
                        (verbose ? BIT_VERBOSE : 0) +
860
 
                        (spstyle ? BIT_SPSTYLE : 0) +
861
 
                        (full_name ? BIT_FULLNAME : 0) +
862
 
                        (home_dir ? BIT_HOMEDIR : 0) +
863
 
                        (home_drive ? BIT_HDIRDRIVE : 0) +
864
 
                        (logon_script ? BIT_LOGSCRIPT : 0) +
865
 
                        (profile_path ? BIT_PROFILE : 0) +
866
 
                        (user_domain ? BIT_USERDOMAIN : 0) +
867
 
                        (machine ? BIT_MACHINE : 0) +
868
 
                        (user_name ? BIT_USER : 0) +
869
 
                        (list_users ? BIT_LIST : 0) +
870
 
                        (force_initialised_password ? BIT_FIX_INIT : 0) +
871
 
                        (user_sid ? BIT_USERSIDS : 0) +
872
 
                        (modify_user ? BIT_MODIFY : 0) +
873
 
                        (add_user ? BIT_CREATE : 0) +
874
 
                        (delete_user ? BIT_DELETE : 0) +
875
 
                        (account_control ? BIT_ACCTCTRL : 0) +
876
 
                        (account_policy ? BIT_ACCPOLICY : 0) +
877
 
                        (account_policy_value_set ? BIT_ACCPOLVAL : 0) +
878
 
                        (backend_in ? BIT_IMPORT : 0) +
879
 
                        (backend_out ? BIT_EXPORT : 0) +
880
 
                        (badpw_reset ? BIT_BADPWRESET : 0) +
881
 
                        (hours_reset ? BIT_LOGONHOURS : 0) +
882
 
                        (pwd_can_change_time ? BIT_CAN_CHANGE: 0) +
883
 
                        (pwd_must_change_time ? BIT_MUST_CHANGE: 0);
884
 
 
885
 
        if (setparms & BIT_BACKEND) {
886
 
                if (!NT_STATUS_IS_OK(make_pdb_method_name( &bdef, backend ))) {
887
 
                        fprintf(stderr, "Can't initialize passdb backend.\n");
888
 
                        return 1;
889
 
                }
890
 
        } else {
891
 
                if (!NT_STATUS_IS_OK(make_pdb_method_name(&bdef, lp_passdb_backend()))) {
892
 
                        fprintf(stderr, "Can't initialize passdb backend.\n");
893
 
                        return 1;
894
 
                }
895
 
        }
896
 
        
897
 
        /* the lowest bit options are always accepted */
898
 
        checkparms = setparms & ~MASK_ALWAYS_GOOD;
899
 
 
900
 
        if (checkparms & BIT_FIX_INIT) {
901
 
                return fix_users_list(bdef);
902
 
        }
903
 
 
904
 
        /* account policy operations */
905
 
        if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) {
906
 
                uint32 value;
907
 
                int field = account_policy_name_to_fieldnum(account_policy);
908
 
                if (field == 0) {
909
 
                        char *apn = account_policy_names_list();
910
 
                        fprintf(stderr, "No account policy by that name\n");
911
 
                        if (apn) {
912
 
                                fprintf(stderr, "Account policy names are :\n%s\n", apn);
913
 
                        }
914
 
                        SAFE_FREE(apn);
915
 
                        exit(1);
916
 
                }
917
 
                if (!pdb_get_account_policy(field, &value)) {
918
 
                        fprintf(stderr, "valid account policy, but unable to fetch value!\n");
919
 
                        if (!account_policy_value_set)
920
 
                                exit(1);
921
 
                }
922
 
                printf("account policy \"%s\" description: %s\n", account_policy, account_policy_get_desc(field));
923
 
                if (account_policy_value_set) {
924
 
                        printf("account policy \"%s\" value was: %u\n", account_policy, value);
925
 
                        if (!pdb_set_account_policy(field, account_policy_value)) {
926
 
                                fprintf(stderr, "valid account policy, but unable to set value!\n");
927
 
                                exit(1);
928
 
                        }
929
 
                        printf("account policy \"%s\" value is now: %lu\n", account_policy, account_policy_value);
930
 
                        exit(0);
931
 
                } else {
932
 
                        printf("account policy \"%s\" value is: %u\n", account_policy, value);
933
 
                        exit(0);
934
 
                }
935
 
        }
936
 
 
937
 
        if (reset_account_policies) {
938
 
                if (!reinit_account_policies()) {
939
 
                        exit(1);
940
 
                }
941
 
 
942
 
                exit(0);
943
 
        }
944
 
 
945
 
        /* import and export operations */
946
 
 
947
 
        if ( ((checkparms & BIT_IMPORT) 
948
 
                || (checkparms & BIT_EXPORT))
949
 
                && !(checkparms & ~(BIT_IMPORT +BIT_EXPORT +BIT_USER)) ) 
950
 
        {
951
 
                NTSTATUS status;
952
 
 
953
 
                bin = bout = bdef;
954
 
 
955
 
                if (backend_in) {
956
 
                        status = make_pdb_method_name(&bin, backend_in);
957
 
 
958
 
                        if ( !NT_STATUS_IS_OK(status) ) {
959
 
                                fprintf(stderr, "Unable to initialize %s.\n", backend_in);
960
 
                                return 1;
961
 
                        }
962
 
                }
963
 
 
964
 
                if (backend_out) {
965
 
                        status = make_pdb_method_name(&bout, backend_out);
966
 
 
967
 
                        if ( !NT_STATUS_IS_OK(status) ) {
968
 
                                fprintf(stderr, "Unable to initialize %s.\n", backend_out);
969
 
                                return 1;
970
 
                        }
971
 
                }
972
 
 
973
 
                if (transfer_account_policies) {
974
 
 
975
 
                        if (!(checkparms & BIT_USER))
976
 
                                return export_account_policies(bin, bout);
977
 
 
978
 
                } else  if (transfer_groups) {
979
 
 
980
 
                        if (!(checkparms & BIT_USER))
981
 
                                return export_groups(bin, bout);
982
 
 
983
 
                } else {
984
 
                                return export_database(bin, bout, 
985
 
                                        (checkparms & BIT_USER) ? user_name : NULL );
986
 
                }
987
 
        }
988
 
 
989
 
        /* if BIT_USER is defined but nothing else then threat it as -l -u for compatibility */
990
 
        /* fake up BIT_LIST if only BIT_USER is defined */
991
 
        if ((checkparms & BIT_USER) && !(checkparms & ~BIT_USER)) {
992
 
                checkparms += BIT_LIST;
993
 
        }
994
 
        
995
 
        /* modify flag is optional to maintain backwards compatibility */
996
 
        /* fake up BIT_MODIFY if BIT_USER  and at least one of MASK_USER_GOOD is defined */
997
 
        if (!((checkparms & ~MASK_USER_GOOD) & ~BIT_USER) && (checkparms & MASK_USER_GOOD)) {
998
 
                checkparms += BIT_MODIFY;
999
 
        }
1000
 
 
1001
 
        /* list users operations */
1002
 
        if (checkparms & BIT_LIST) {
1003
 
                if (!(checkparms & ~BIT_LIST)) {
1004
 
                        return print_users_list (bdef, verbose, spstyle);
1005
 
                }
1006
 
                if (!(checkparms & ~(BIT_USER + BIT_LIST))) {
1007
 
                        return print_user_info (bdef, user_name, verbose, spstyle);
1008
 
                }
1009
 
        }
1010
 
        
1011
 
        /* mask out users options */
1012
 
        checkparms &= ~MASK_USER_GOOD;
1013
 
 
1014
 
        /* if bad password count is reset, we must be modifying */
1015
 
        if (checkparms & BIT_BADPWRESET) {
1016
 
                checkparms |= BIT_MODIFY;
1017
 
                checkparms &= ~BIT_BADPWRESET;
1018
 
        }
1019
 
 
1020
 
        /* if logon hours is reset, must modify */
1021
 
        if (checkparms & BIT_LOGONHOURS) {
1022
 
                checkparms |= BIT_MODIFY;
1023
 
                checkparms &= ~BIT_LOGONHOURS;
1024
 
        }
1025
 
        
1026
 
        /* account operation */
1027
 
        if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) {
1028
 
                /* check use of -u option */
1029
 
                if (!(checkparms & BIT_USER)) {
1030
 
                        fprintf (stderr, "Username not specified! (use -u option)\n");
1031
 
                        return -1;
1032
 
                }
1033
 
 
1034
 
                /* account creation operations */
1035
 
                if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE))) {
1036
 
                        if (checkparms & BIT_MACHINE) {
1037
 
                                return new_machine (bdef, user_name);
1038
 
                        } else {
1039
 
                                return new_user (bdef, user_name, full_name, home_dir, 
1040
 
                                        home_drive, logon_script, profile_path, user_sid, pw_from_stdin);
1041
 
                        }
1042
 
                }
1043
 
 
1044
 
                /* account deletion operations */
1045
 
                if (!(checkparms & ~(BIT_DELETE + BIT_USER + BIT_MACHINE))) {
1046
 
                        if (checkparms & BIT_MACHINE) {
1047
 
                                return delete_machine_entry (bdef, user_name);
1048
 
                        } else {
1049
 
                                return delete_user_entry (bdef, user_name);
1050
 
                        }
1051
 
                }
1052
 
 
1053
 
                /* account modification operations */
1054
 
                if (!(checkparms & ~(BIT_MODIFY + BIT_USER))) {
1055
 
                        time_t pwd_can_change = -1;
1056
 
                        time_t pwd_must_change = -1;
1057
 
                        const char *errstr;
1058
 
 
1059
 
                        if (pwd_can_change_time) {
1060
 
                                errstr = "can";
1061
 
                                if (pwd_time_format) {
1062
 
                                        struct tm tm;
1063
 
                                        char *ret;
1064
 
 
1065
 
                                        memset(&tm, 0, sizeof(struct tm));
1066
 
                                        ret = strptime(pwd_can_change_time, pwd_time_format, &tm);
1067
 
                                        if (ret == NULL || *ret != '\0') {
1068
 
                                                goto error;
1069
 
                                        }
1070
 
 
1071
 
                                        pwd_can_change = mktime(&tm);
1072
 
 
1073
 
                                        if (pwd_can_change == -1) {
1074
 
                                                goto error;
1075
 
                                        }
1076
 
                                } else { /* assume it is unix time */
1077
 
                                        errno = 0;
1078
 
                                        pwd_can_change = strtol(pwd_can_change_time, NULL, 10);
1079
 
                                        if (errno) {
1080
 
                                                goto error;
1081
 
                                        }
1082
 
                                }       
1083
 
                        }
1084
 
                        if (pwd_must_change_time) {
1085
 
                                errstr = "must";
1086
 
                                if (pwd_time_format) {
1087
 
                                        struct tm tm;
1088
 
                                        char *ret;
1089
 
 
1090
 
                                        memset(&tm, 0, sizeof(struct tm));
1091
 
                                        ret = strptime(pwd_must_change_time, pwd_time_format, &tm);
1092
 
                                        if (ret == NULL || *ret != '\0') {
1093
 
                                                goto error;
1094
 
                                        }
1095
 
 
1096
 
                                        pwd_must_change = mktime(&tm);
1097
 
 
1098
 
                                        if (pwd_must_change == -1) {
1099
 
                                                goto error;
1100
 
                                        }
1101
 
                                } else { /* assume it is unix time */
1102
 
                                        errno = 0;
1103
 
                                        pwd_must_change = strtol(pwd_must_change_time, NULL, 10);
1104
 
                                        if (errno) {
1105
 
                                                goto error;
1106
 
                                        }
1107
 
                                }       
1108
 
                        }
1109
 
                        return set_user_info (bdef, user_name, full_name, home_dir,
1110
 
                                acct_desc, home_drive, logon_script, profile_path, account_control,
1111
 
                                user_sid, user_domain, badpw_reset, hours_reset, pwd_can_change, 
1112
 
                                pwd_must_change);
1113
 
error:
1114
 
                        fprintf (stderr, "Error parsing the time in pwd-%s-change-time!\n", errstr);
1115
 
                        return -1;
1116
 
                }
1117
 
        }
1118
 
 
1119
 
        if (setparms >= 0x20) {
1120
 
                fprintf (stderr, "Incompatible or insufficient options on command line!\n");
1121
 
        }
1122
 
        poptPrintHelp(pc, stderr, 0);
1123
 
 
1124
 
        return 1;
1125
 
}