Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / uss / uss.c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10 /*
11 * Main module for the AFS user account management tool.
12 */
13
14 /*
15 * --------------------- Required definitions ---------------------
16 */
17 #include <afsconfig.h>
18 #include <afs/param.h>
19
20 #include <roken.h>
21
22 #include <afs/cmd.h> /*Command line parsing */
23 #include <afs/cellconfig.h> /*Cell config defs */
24 #include <afs/kautils.h> /*MAXKTCREALMLEN & MAXKTCNAMELEN */
25 #include <afs/pterror.h>
26 #include <afs/vlserver.h>
27 #include <ubik.h>
28
29 #include "uss_common.h" /*Common uss definitions, globals */
30 #include "uss_procs.h" /*Main uss operations */
31 #include "uss_kauth.h" /*AuthServer routines */
32 #include "uss_fs.h" /*CacheManager ops */
33 #include "uss_ptserver.h"
34 #include "uss_vol.h"
35 #include "uss_acl.h"
36
37 extern int yylex(void);
38 extern int yyparse (void);
39 /*
40 * Label certain things which will be activated at a later time,
41 * as well as certain semi-implemented features/switches which need
42 * to be hidden for the general AFS 3.2 release.
43 */
44 #define USS_FUTURE_FEATURES 1
45 #define USS_DONT_HIDE_SOME_FEATURES 0
46
47 /*
48 * ---------------------- Exported variables ----------------------
49 */
50 char *uss_fs_InBuff = NULL; /*Cache Manager input buff */
51 char *uss_fs_OutBuff = NULL; /*Cache Manager output buff */
52
53 /*
54 * Set up convenient tags for the command line parameter indicies.
55 */
56
57 /*Add*/
58 #define AUP_USER 0
59 #define AUP_REALNAME 1
60 #define AUP_PASSWD 2
61 #define AUP_PWEXPIRES 3
62 #define AUP_SERVER 4 /* was 3 */
63 #define AUP_PART 5 /* was 4 */
64 #define AUP_MNTPT 6 /* was 5 */
65 #define AUP_UID 7 /* was 6 */
66
67 /*Bulk*/
68 #define ABULK_FILE 0
69
70 extern int uss_perr;
71 /*Delete*/
72 #define DUP_USER 0
73 #define DUP_MNTPT 1
74 #define DUP_RESTOREDIR 2
75 #define DUP_SAVEVOLUME 3
76 #define DUP_PWDPATH 4
77 #define DUP_PWDFORMAT 5
78
79 /*PurgeVolumes*/
80 #define PVP_VOLNAME 0
81 #define PVP_VOLFILE 1
82
83 /*Common ones*/
84 #define AUSS_TEMPLATE 10 /* was 7 */
85 #define AUSS_VERBOSE 11 /* was 8 */
86 #define AUSS_VAR 12 /* was 9 */
87 #define AUSS_CELL 13 /* was 10 */
88 #define AUSS_ADMIN 14 /* was 11 */
89 #define AUSS_DRYRUN 15 /* was 12 */
90 #define AUSS_SKIPAUTH 16 /* was 13 */
91 #define AUSS_OVERWRITE 17 /* was 14 */
92 #define AUSS_PWEXPIRES 18 /* was 15 */
93 #define AUSS_PIPE 19 /* was 16 */
94
95 #undef USS_DB
96
97 static char Template[300] = "uss.template"; /*Default name */
98
99 extern FILE *uss_yyin, *uss_yyout; /*YACC input & output files */
100 extern int doUnlog;
101 int uss_BulkExpires = 0;
102 int local_Cell = 1;
103
104 static int DoAdd(void);
105
106 /*-----------------------------------------------------------------------
107 * static GetCommon
108 *
109 * Description:
110 * Read in the command line arguments common to all uss operations.
111 *
112 * Arguments:
113 * a_as : Ptr to the command line syntax descriptor.
114 *
115 * Returns:
116 * 0 (always)
117 *
118 * Environment:
119 * May exit the program if trouble is encountered determining the
120 * cell name. Set up as the command line parser's BeforeProc().
121 *
122 * Side Effects:
123 * As advertised.
124 *------------------------------------------------------------------------*/
125
126 static int
127 GetCommon(struct cmd_syndesc *a_as, void *arock)
128 { /*GetCommon */
129
130 int code; /*Result of ka_LocalCell */
131
132 if (strcmp(a_as->name, "help") == 0)
133 return 0;
134 if (a_as->parms[AUSS_TEMPLATE].items)
135 strcpy(Template, a_as->parms[AUSS_TEMPLATE].items->data);
136 if (a_as->parms[AUSS_VERBOSE].items)
137 uss_verbose = 1;
138 else
139 uss_verbose = 0;
140
141 code = ka_CellConfig(AFSDIR_CLIENT_ETC_DIRPATH);
142 if (code)
143 fprintf(stderr, "%s: ** Call to ka_CellConfig() failed (code=%d)\n",
144 uss_whoami, code);
145
146 if (a_as->parms[AUSS_CELL].items) {
147 char local_cell[MAXKTCREALMLEN];
148 if (ka_ExpandCell
149 (a_as->parms[AUSS_CELL].items->data, uss_Cell, 0 /*local */ )) {
150 fprintf(stderr, "%s: ** Unknown or ambiguous cell name: %s\n",
151 uss_whoami, a_as->parms[AUSS_CELL].items->data);
152 exit(-1);
153 }
154 /*
155 * Get the local cell name
156 */
157 if (ka_ExpandCell((char *)0, local_cell, 0 /*local */ )) {
158 fprintf(stderr, "Can't get local cellname\n");
159 exit(-1);
160 }
161 if (strcmp(uss_Cell, local_cell)) {
162 /*
163 * Not the same; not a local cell
164 */
165 local_Cell = 0;
166 }
167 } else {
168 /*
169 * Get the local cell name
170 */
171 if (ka_ExpandCell((char *)0, uss_Cell, 0 /*local */ )) {
172 fprintf(stderr, "Can't get local cellname\n");
173 exit(-1);
174 }
175 if (uss_verbose)
176 fprintf(stderr, "No cell specified; assuming '%s'.\n", uss_Cell);
177 }
178
179 return (0);
180
181 } /*GetCommon */
182
183
184 /*-----------------------------------------------------------------------
185 * static SaveRestoreInfo
186 *
187 * Description:
188 * Save all the information required to restore the currently
189 * parsed user account.
190 *
191 * Arguments:
192 * None.
193 *
194 * Returns:
195 * 0 if everything went well,
196 * 1 if something went wrong in the function, or
197 * Lower-level error code if something went wrong below us.
198 *
199 * Environment:
200 * We need to determine and store the following new pieces of
201 * information:
202 * User's AFS ID
203 * Name of user's volume
204 * FileServer & partition hosting the volume
205 *
206 * Side Effects:
207 * As advertised.
208 *------------------------------------------------------------------------*/
209
210 static int
211 SaveRestoreInfo(void)
212 { /*SaveRestoreInfo */
213 #ifdef USS_DB
214 static char rn[] = "uss:SaveRestoreInfo"; /*Routine name */
215 #endif
216 afs_int32 code; /*Return code */
217 afs_int32 deletedUid; /*Uid to be nuked */
218
219 /*
220 * Translate the user name to the user ID.
221 */
222 code = uss_ptserver_XlateUser(uss_User, &deletedUid);
223 if (code)
224 return (code);
225 #ifdef USS_DB
226 printf("%s: User '%s' translated to uid %d\n", rn, uss_User, deletedUid);
227 #endif /* USS_DB */
228 sprintf(uss_Uid, "%d", deletedUid);
229
230 /*
231 * Pull out the name of the volume at the given mountpoint, along
232 * with the name of the FileServer and partition hosting it. This
233 * also sets up all the numerical info for the above.
234 */
235 code = uss_vol_GetVolInfoFromMountPoint(uss_MountPoint);
236 if (code)
237 return (code);
238
239 /*
240 * Report back that we did fine.
241 */
242 return (0);
243
244 } /*SaveRestoreInfo */
245
246
247 /*-----------------------------------------------------------------------
248 * static DoDelete
249 *
250 * Description:
251 * With everything properly inserted into the common variables,
252 * delete the specified user account.
253 *
254 * Arguments:
255 * None.
256 *
257 * Returns:
258 * 0 if everything went well,
259 * 1 if something went wrong in the function, or
260 * Lower-level error code if something went wrong below us.
261 *
262 * Environment:
263 * Nothing interesting.
264 *
265 * Side Effects:
266 * As advertised.
267 *------------------------------------------------------------------------*/
268
269 static int
270 DoDelete(void)
271 { /*DoDelete */
272
273 int code; /*Return code */
274
275 /*
276 * Make sure the user name is a lega one.
277 */
278 code = uss_kauth_CheckUserName();
279 if (code)
280 return (code);
281
282 /*
283 * Store all the info about the account before actually doing
284 * anything.
285 */
286 code = SaveRestoreInfo();
287 if (code)
288 return (code);
289
290 if ((uss_VolumeID != 0) && (uss_MountPoint[0] != '\0')) {
291 /*
292 * Unmount the user's volume from the file system.
293 */
294 if (uss_verbose) {
295 fprintf(stderr,
296 "Unmounting volume '%s' (ID %u) mounted at '%s'\n",
297 uss_Volume, uss_VolumeID, uss_MountPoint);
298 }
299
300 code = uss_fs_RmMountPoint(uss_MountPoint);
301 if (code) {
302 if (uss_verbose)
303 fprintf(stderr, "%s: Can't remove mountpoint '%s'\n",
304 uss_whoami, uss_MountPoint);
305 return (code); /* Must return - we may have incorrect volume */
306 }
307 }
308
309 /*
310 * If our caller has elected to delete the user's volume now,
311 * then do so.
312 */
313 if (!uss_SaveVolume && (uss_VolumeID != 0)) {
314 if (uss_verbose) {
315 fprintf(stderr, "Deleting volume '%s' (ID %u)\n", uss_Volume,
316 uss_VolumeID);
317 }
318
319 code =
320 uss_vol_DeleteVol(uss_Volume, uss_VolumeID, uss_Server,
321 uss_ServerID, uss_Partition, uss_PartitionID);
322 if (code) {
323 if (uss_verbose)
324 fprintf(stderr, "%s: Can't delete volume '%s' (ID %u)\n",
325 uss_whoami, uss_Volume, uss_VolumeID);
326 return (code);
327 }
328 } else if (uss_verbose && (uss_MountPoint[0] != '\0'))
329 printf("%s: Warning: Not attempting to delete volume at '%s'\n",
330 uss_whoami, uss_MountPoint);
331
332 /*
333 * Get rid of the user's authentication entry.
334 */
335 code = uss_kauth_DelUser(uss_User);
336 if (code)
337 return (code);
338
339 /*
340 * Finally, remove the user's AFS ID from the Protection DB and
341 * return that result.
342 */
343 code = uss_ptserver_DelUser(uss_User);
344 return (code);
345
346 } /*DoDelete */
347
348
349 /*-----------------------------------------------------------------------
350 * static DelUser
351 *
352 * Description:
353 * Process the given (non-bulk) delete command.
354 *
355 * Arguments:
356 * a_as : Ptr to the command line syntax descriptor.
357 * a_rock : Ptr to the rock passed in.
358 *
359 * Returns:
360 * 0 if everything went well,
361 * 1 if something went wrong in the function, or
362 * Lower-level error code if something went wrong below us.
363 *
364 * Environment:
365 * Nothing interesting.
366 *
367 * Side Effects:
368 * As advertised.
369 *------------------------------------------------------------------------*/
370
371 static int
372 DelUser(struct cmd_syndesc *a_as, void *a_rock)
373 { /*DelUser */
374
375 int code;
376
377 /*
378 * Before we do anything else, make sure we initialize the
379 * global field settings.
380 */
381 uss_common_Reset();
382
383 /*
384 * Pull out the fields as passed in by the caller on the command
385 * line.
386 */
387 strcpy(uss_User, a_as->parms[DUP_USER].items->data);
388 if (a_as->parms[DUP_MNTPT].items)
389 strcpy(uss_MountPoint, a_as->parms[DUP_MNTPT].items->data);
390 #if USS_FUTURE_FEATURES
391 #if USS_DONT_HIDE_SOME_FEATURES
392 strcpy(uss_RestoreDir, a_as->parms[DUP_RESTOREDIR].items->data);
393 #endif /* USS_DONT_HIDE_SOME_FEATURES */
394 #endif /* USS_FUTURE_FEATURES */
395
396 /*
397 if (a_as->parms[DUP_SAVEVOLUME].items)
398 uss_SaveVolume = 1;
399 */
400
401 if (a_as->parms[2].items) {
402 uss_SaveVolume = 1;
403 }
404 #if USS_FUTURE_FEATURES
405 #if USS_DONT_HIDE_SOME_FEATURES
406 if (a_as->parms[DUP_PWDPATH].items)
407 strcpy(uss_PwdPath, a_as->parms[DUP_PWDPATH].items->data);
408 if (a_as->parms[DUP_PWDFORMAT].items)
409 strcpy(uss_PwdFormat, a_as->parms[DUP_PWDFORMAT].items->data);
410 #endif /* USS_DONT_HIDE_SOME_FEATURES */
411 #endif /* USS_FUTURE_FEATURES */
412
413 if (a_as->parms[AUSS_DRYRUN].items)
414 uss_DryRun = 1;
415 if (a_as->parms[AUSS_SKIPAUTH].items)
416 uss_SkipKaserver = 1;
417 if (a_as->parms[AUSS_ADMIN].items) {
418 strcpy(uss_Administrator, a_as->parms[AUSS_ADMIN].items->data);
419 /* fprintf(stderr, "debugging: uss_Administrator set to '%s'\n",
420 * uss_Administrator); */
421 } else {
422 /* fprintf(stderr, "debugging: No administrator value given\n"); */
423 uss_Administrator[0] = '\0';
424 }
425
426 /*
427 * Initialize uss_AccountCreator().
428 */
429 code = uss_kauth_InitAccountCreator();
430 if (code)
431 return (code);
432
433 /*
434 * Now that the command line arguments are parsed and properly stored,
435 * go for it!
436 */
437
438 return (DoDelete());
439
440 } /*DelUser */
441
442 #if USS_FUTURE_FEATURES
443 #if USS_DONT_HIDE_SOME_FEATURES
444 /*-----------------------------------------------------------------------
445 * static PurgeVolumes
446 *
447 * Description:
448 * Purge the given volume(s).
449 *
450 * Arguments:
451 * a_as : Ptr to the command line syntax descriptor.
452 * a_rock : Ptr to the rock passed in.
453 *
454 * Returns:
455 * 0 if everything went well,
456 * 1 if something went wrong in the function, or
457 * Lower-level error code if something went wrong below us.
458 *
459 * Environment:
460 * Nothing interesting.
461 *
462 * Side Effects:
463 * As advertised.
464 *------------------------------------------------------------------------*/
465
466 static int
467 PurgeVolumes(struct cmd_syndesc *a_as, void *a_rock)
468 { /*PurgeVolumes */
469
470 fprintf(stderr, "Sorry, purgevolumes has not yet been implemented.\n");
471 return (0);
472
473 } /*PurgeVolumes */
474
475
476 /*-----------------------------------------------------------------------
477 * static RestoreUser
478 *
479 * Description:
480 * Process the given delete command.
481 *
482 * Arguments:
483 * a_as : Ptr to the command line syntax descriptor.
484 * a_rock : Ptr to the rock passed in.
485 *
486 * Returns:
487 * 0 if everything went well,
488 * 1 if something went wrong in the function, or
489 * Lower-level error code if something went wrong below us.
490 *
491 * Environment:
492 * Nothing interesting.
493 *
494 * Side Effects:
495 * As advertised.
496 *------------------------------------------------------------------------*/
497
498 static int
499 RestoreUser(struct cmd_syndesc *a_as, void *a_rock)
500 { /*RestoreUser */
501
502 fprintf(stderr, "Sorry, restoreuser has not yet been implemented.\n");
503 return (0);
504
505 } /*RestoreUser */
506
507 #endif
508 #endif
509
510 /*-----------------------------------------------------------------------
511 * static DoBulkAddLine
512 *
513 * Description:
514 * Process the given bulk add command.
515 *
516 * Arguments:
517 * a_buf : Ptr to the buffer holding the bulk add command.
518 * a_tp : Ptr to the first char past the opcode.
519 *
520 * Returns:
521 * 0 if everything went well,
522 * -1 if something went wrong in the function, or
523 * Lower-level error code if something went wrong below us.
524 *
525 * Environment:
526 * The required fields are:
527 * -user
528 *
529 * Side Effects:
530 * As advertised.
531 *------------------------------------------------------------------------*/
532
533 static int
534 DoBulkAddLine(char *a_buf, char *a_tp)
535 { /*DoBulkAddLine */
536
537 int i; /*Loop variable */
538 #ifdef USS_DB
539 static char rn[] = "DoBulkAddLine"; /*Routine name */
540 #endif
541 int overflow; /*Overflow in field copy? */
542
543 #ifdef USS_DB
544 printf("%s: Command buffer left to parse: '%s'\n", rn, a_tp);
545 #endif /* USS_DB */
546 uss_Expires = uss_BulkExpires;
547
548 /*
549 * Pull out all the fields.
550 */
551 a_tp = uss_common_FieldCp(uss_User, a_tp, ':', uss_UserLen, &overflow);
552 if (overflow) {
553 fprintf(stderr,
554 "%s: * User field in add cmd too long (max is %d chars; truncated value is '%s')\n",
555 uss_whoami, uss_UserLen, uss_User);
556 return (-1);
557 }
558 if ((*a_tp == '\0') || (*a_tp == '\n')) {
559 fprintf(stderr,
560 "%s: * The user field must appear in a bulk add command.\n",
561 uss_whoami);
562 return (-1);
563 }
564
565 a_tp =
566 uss_common_FieldCp(uss_RealName, a_tp, ':', uss_RealNameLen,
567 &overflow);
568 if (overflow) {
569 fprintf(stderr,
570 "%s: * Real name field in add cmd too long (max is %d chars; truncated value is '%s')\n",
571 uss_whoami, uss_RealNameLen, uss_RealName);
572 return (-1);
573 }
574 if (uss_RealName[0] == '\0') {
575 /*
576 * The user's real name has not been supplied. As a
577 * default, we use the account name.
578 */
579 sprintf(uss_RealName, "%s", uss_User);
580 if (uss_verbose)
581 fprintf(stderr, "%s: Using default real name, '%s'\n", uss_whoami,
582 uss_User);
583 }
584 /*Use default full name */
585 a_tp = uss_common_FieldCp(uss_Pwd, a_tp, ':', uss_PwdLen, &overflow);
586 if (overflow) {
587 fprintf(stderr,
588 "%s: * Password field in add cmd too long (max is %d chars; truncated value is '%s')\n",
589 uss_whoami, uss_PwdLen, uss_Pwd);
590 return (-1);
591 }
592 if (uss_Pwd[0] == '\0') {
593 /*
594 * The user's password has not been provided. Use
595 * the default.
596 */
597 sprintf(uss_Pwd, "%s", uss_DEFAULT_PASSWORD);
598 if (uss_verbose)
599 fprintf(stderr, "%s: Using default password, '%s'\n", uss_whoami,
600 uss_Pwd);
601 } /*Use default password */
602 if ((*a_tp == '\0') || (*a_tp == '\n'))
603 goto DoBulkAddLine_ParsingDone;
604
605
606 {
607 char temp[10];
608 a_tp = uss_common_FieldCp(temp, a_tp, ':', 9, &overflow);
609 if (overflow) {
610 fprintf(stderr,
611 "%s: * Password expiration time is longer than %d characters, ignoring...\n",
612 uss_whoami, 9);
613 }
614 if (temp[0] == '\0') {
615 /* Expiration time not specified. Use default */
616 if (uss_verbose)
617 fprintf(stderr, "%s: Using default expiration time, '%d'\n",
618 uss_whoami, uss_Expires);
619 } else {
620 int te;
621 te = atoi(temp);
622 if (te < 0 || te > 254) {
623 fprintf(stderr,
624 "%s: * Password Expiration must be in [0..254] days, using default %d\n",
625 uss_whoami, uss_Expires);
626 } else
627 uss_Expires = te;
628 }
629
630 if ((*a_tp == '\0') || (*a_tp == '\n'))
631 goto DoBulkAddLine_ParsingDone;
632 }
633
634
635 a_tp =
636 uss_common_FieldCp(uss_Server, a_tp, ':', uss_ServerLen, &overflow);
637 if (overflow) {
638 fprintf(stderr,
639 "%s: * Server field in add cmd too long (max is %d chars; truncated value is '%s')\n",
640 uss_whoami, uss_ServerLen, uss_Server);
641 return (-1);
642 }
643 if ((*a_tp == '\0') || (*a_tp == '\n'))
644 goto DoBulkAddLine_ParsingDone;
645
646 a_tp =
647 uss_common_FieldCp(uss_Partition, a_tp, ':', uss_PartitionLen,
648 &overflow);
649 if (overflow) {
650 fprintf(stderr,
651 "%s: * Partition field in add cmd too long (max is %d chars; truncated value is '%s')\n",
652 uss_whoami, uss_PartitionLen, uss_Partition);
653 return (-1);
654 }
655 if ((*a_tp == '\0') || (*a_tp == '\n'))
656 goto DoBulkAddLine_ParsingDone;
657
658 a_tp =
659 uss_common_FieldCp(uss_MountPoint, a_tp, ':', uss_MountPointLen,
660 &overflow);
661 if (overflow) {
662 fprintf(stderr,
663 "%s: * Mountpoint field in add cmd too long (max is %d chars; truncated value is '%s')\n",
664 uss_whoami, uss_MountPointLen, uss_MountPoint);
665 return (-1);
666 }
667 if ((*a_tp == '\0') || (*a_tp == '\n'))
668 goto DoBulkAddLine_ParsingDone;
669
670 a_tp = uss_common_FieldCp(uss_Uid, a_tp, ':', uss_UidLen, &overflow);
671 if (overflow) {
672 fprintf(stderr,
673 "%s: * UID field in add cmd too long (max is %d chars; truncated value is '%s')\n",
674 uss_whoami, uss_UidLen, uss_Uid);
675 return (-1);
676 }
677 uss_DesiredUID = atoi(uss_Uid);
678 if ((*a_tp == '\0') || (*a_tp == '\n'))
679 goto DoBulkAddLine_ParsingDone;
680
681 for (uss_VarMax = 1; uss_VarMax < 10; uss_VarMax++) {
682 a_tp =
683 uss_common_FieldCp(uss_Var[uss_VarMax], a_tp, ':',
684 uss_MAX_ARG_SIZE, &overflow);
685 if (overflow) {
686 fprintf(stderr,
687 "%s: * Variable %d field in add cmd too long (max is %d chars; truncated value is '%s')\n",
688 uss_whoami, uss_VarMax, uss_MAX_ARG_SIZE,
689 uss_Var[uss_VarMax]);
690 return (-1);
691 }
692 if ((*a_tp == '\0') || (*a_tp == '\n'))
693 goto DoBulkAddLine_ParsingDone;
694 }
695
696 DoBulkAddLine_ParsingDone:
697 /*
698 * If there's anything left on the line, we ignore it. Announce
699 * the bulk add parameters we've parsed or filled in if we're
700 * being verbose, then go for it.
701 */
702 if (uss_verbose) {
703 fprintf(stderr,
704 "\nAdding user '%s' ('%s'), password='%s' on server '%s', partition '%s', home directory='%s'",
705 uss_User, uss_RealName, uss_Pwd,
706 (uss_Server[0] != '\0' ? uss_Server : "<default>"),
707 (uss_Partition[0] != '\0' ? uss_Partition : "<default>"),
708 (uss_MountPoint[0] != '\0' ? uss_MountPoint : "<default>"));
709 if (uss_DesiredUID)
710 fprintf(stderr, ", uid preset to %d\n", uss_DesiredUID);
711 else
712 fprintf(stderr, ", no preset uid\n");
713 for (i = 1; i <= uss_VarMax; i++) {
714 if (uss_Var[i][0] != '\0')
715 fprintf(stderr, "$%1d='%s' ", i, uss_Var[i]);
716 }
717 if (uss_VarMax > 0)
718 fprintf(stderr, "\n");
719 }
720
721 /*Verbose status of add command */
722 /*
723 * Now do the real work.
724 */
725 return (DoAdd());
726
727 } /*DoBulkAddLine */
728
729
730 /*-----------------------------------------------------------------------
731 * static DoBulkDeleteLine
732 *
733 * Description:
734 * Process the given bulk delete command.
735 *
736 * Arguments:
737 * a_buf : Ptr to the buffer holding the bulk delete command.
738 * a_tp : Ptr to the first char past the opcode.
739 *
740 * Returns:
741 * 0 if everything went well,
742 * -1 if something went wrong in the function, or
743 * Lower-level error code if something went wrong below us.
744 *
745 * Environment:
746 * The required fields are:
747 * -user, -mountpoint, -restoredir
748 *
749 * Side Effects:
750 * As advertised.
751 *------------------------------------------------------------------------*/
752
753 static int
754 DoBulkDeleteLine(char *a_buf, char *a_tp)
755 { /*DoBulkDeleteLine */
756
757 char volField[32]; /*Value of optional vol disposition field */
758 int overflow; /*Was there an overflow in field copying? */
759
760 /*
761 * Pull out all the fields.
762 */
763 a_tp = uss_common_FieldCp(uss_User, a_tp, ':', uss_UserLen, &overflow);
764 if (overflow) {
765 fprintf(stderr,
766 "%s: * User field in delete cmd too long (max is %d chars; truncated value is '%s')\n",
767 uss_whoami, uss_UserLen, uss_User);
768 return (-1);
769 }
770 if ((uss_User[0] == '\0') || (*a_tp == '\0') || (*a_tp == '\n'))
771 goto Delete_MissingRequiredParam;
772
773 a_tp =
774 uss_common_FieldCp(uss_MountPoint, a_tp, ':', uss_MountPointLen,
775 &overflow);
776 if (overflow) {
777 fprintf(stderr,
778 "%s: * Mountpoint field in delete cmd too long (max is %d chars; truncated value is '%s')\n",
779 uss_whoami, uss_MountPointLen, uss_MountPoint);
780 return (-1);
781 }
782 #if USS_FUTURE_FEATURES
783 #if USS_DONT_HIDE_SOME_FEATURES
784 if ((uss_MountPoint[0] == '\0') || (*a_tp == '\0') || (*a_tp == '\n'))
785 goto Delete_MissingRequiredParam;
786 #endif /* USS_DONT_HIDE_SOME_FEATURES */
787 #else
788 if ((*a_tp == '\0') || (*a_tp == '\n'))
789 goto Delete_ParsingDone;
790 #endif /* USS_FUTURE_FEATURES */
791
792 #if USS_FUTURE_FEATURES
793 #if USS_DONT_HIDE_SOME_FEATURES
794 a_tp =
795 uss_common_FieldCp(uss_RestoreDir, a_tp, ':', uss_RestoreDirLen,
796 &overflow);
797 if (overflow) {
798 fprintf(stderr,
799 "%s: * RestoreDir field in delete cmd too long (max is %d chars; truncated value is '%s')\n",
800 uss_whoami, uss_RestoreDirLen, uss_RestoreDir);
801 return (-1);
802 }
803 if (uss_RestoreDir[0] == '\0')
804 goto Delete_MissingRequiredParam;
805 if ((*a_tp == '\0') || (*a_tp == '\n'))
806 goto Delete_ParsingDone;
807
808 a_tp =
809 uss_common_FieldCp(uss_PwdPath, a_tp, ':', uss_PwdPathLen, &overflow);
810 if (overflow) {
811 fprintf(stderr,
812 "%s: * Password path field in delete cmd too long (max is %d chars; truncated value is '%s')\n",
813 uss_whoami, uss_PwdPathLen, uss_PwdPath);
814 return (-1);
815 }
816 if ((*a_tp == '\0') || (*a_tp == '\n'))
817 goto Delete_ParsingDone;
818
819 a_tp =
820 uss_common_FieldCp(uss_PwdFormat, a_tp, ':', uss_PwdFormatLen,
821 &overflow);
822 if (overflow) {
823 fprintf(stderr,
824 "%s: * Password format field in delete cmd too long (max is %d chars; truncated value is '%s')\n",
825 uss_whoami, uss_PwdFormatLen, uss_PwdFormat);
826 return (-1);
827 }
828 if ((*a_tp == '\0') || (*a_tp == '\n'))
829 goto Delete_ParsingDone;
830 #endif /* USS_DONT_HIDE_SOME_FEATURES */
831 #endif /* USS_FUTURE_FEATURES */
832
833 a_tp = uss_common_FieldCp(volField, a_tp, ':', 32, &overflow);
834 if (overflow) {
835 fprintf(stderr,
836 "%s: * Volume save/del field in delete cmd too long (max is 32 chars; truncated value is '%s')\n",
837 uss_whoami, volField);
838 return (-1);
839 }
840 if ((*a_tp == '\0') || (*a_tp == '\n'))
841 goto Delete_ParsingDone;
842
843 if (strcmp(volField, "delvolume") == 0)
844 uss_SaveVolume = 0;
845 else
846 uss_SaveVolume = 1;
847
848 Delete_ParsingDone:
849 /*
850 * If there's anything left on the line, we ignore it. Announce
851 * the bulk delete parameters we've parsed if we're being verbose,
852 * then go for it.
853 */
854 if (uss_verbose) {
855 #if USS_FUTURE_FEATURES
856 #if USS_DONT_HIDE_SOME_FEATURES
857 fprintf(stderr,
858 "\nDeleting user '%s' mounted at '%s', restoredir='%s', pwd path='%s', pwd format='%s'",
859 uss_User, uss_MountPoint, uss_RestoreDir, uss_PwdPath,
860 uss_PwdFormat);
861 #endif /* USS_DONT_HIDE_SOME_FEATURES */
862 #else
863 fprintf(stderr, "\nDeleting user '%s' mounted at '%s'", uss_User,
864 uss_MountPoint);
865 #endif /* USS_FUTURE_FEATURES */
866 if (uss_SaveVolume)
867 fprintf(stderr, ", saving user's volume\n");
868 else
869 fprintf(stderr, ", deleting user's volume\n");
870 }
871
872 /*Verbose status of delete command */
873 /*
874 * Now do the real work.
875 */
876 return (DoDelete());
877
878 Delete_MissingRequiredParam:
879 fprintf(stderr,
880 "%s: * All of the user, mountpoint, and restoredir fields must appear in a bulk delete command line.\n",
881 uss_whoami);
882 return (-1);
883
884 } /*DoBulkDeleteLine */
885
886 #if USS_FUTURE_FEATURES
887 #if USS_DONT_HIDE_SOME_FEATURES
888 /*-----------------------------------------------------------------------
889 * static DoBulkPurgeVolumeLine
890 *
891 * Description:
892 * Process the given bulk add command.
893 *
894 * Arguments:
895 * a_buf : Ptr to the buffer holding the bulk add command.
896 * a_tp : Ptr to the first char past the opcode.
897 *
898 * Returns:
899 * 0 if everything went well,
900 * -1 if something went wrong in the function, or
901 * Lower-level error code if something went wrong below us.
902 *
903 * Environment:
904 * Nothing interesting.
905 *
906 * Side Effects:
907 * As advertised.
908 *------------------------------------------------------------------------*/
909
910 static int
911 DoBulkPurgeVolumeLine(char *a_buf, char *a_tp)
912 { /*DoBulkPurgeVolumeLine */
913
914 int i; /*Loop variable */
915 int overflow; /*Did a field copy overflow happen? */
916
917 /*
918 * Pull out all the fields.
919 */
920 a_tp = uss_common_FieldCp(uss_User, a_tp, ':', uss_UserLen, &overflow);
921 if (overflow) {
922 fprintf(stderr,
923 "%s: * User field in purgevolume cmd too long (max is %d chars; truncated value is '%s')\n",
924 uss_whoami, uss_UserLen, uss_User);
925 return (-1);
926 }
927 if ((*a_tp == '\0') || (*a_tp == '\n')) {
928 fprintf(stderr,
929 "%s: * The user field must appear in a bulk add command.\n",
930 uss_whoami);
931 return (-1);
932 }
933
934 a_tp =
935 uss_common_FieldCp(uss_RealName, a_tp, ':', uss_RealNameLen,
936 &overflow);
937 if (overflow) {
938 fprintf(stderr,
939 "%s: * Real name field in purgevolume cmd too long (max is %d chars; truncated value is '%s')\n",
940 uss_whoami, uss_RealNameLen, uss_RealName);
941 return (-1);
942 }
943 if (uss_RealName[0] == '\0') {
944 /*
945 * The user's real name has not been supplied. As a
946 * default, we use the account name.
947 */
948 sprintf(uss_RealName, "%s", uss_User);
949 if (uss_verbose)
950 fprintf(stderr, "%s: Using default real name, '%s'\n", uss_whoami,
951 uss_User);
952 }
953 /*Use default full name */
954 a_tp = uss_common_FieldCp(uss_Pwd, a_tp, ':', uss_PwdLen, &overflow);
955 if (overflow) {
956 fprintf(stderr,
957 "%s: * Password field in purgevolume cmd too long (max is %d chars; truncated value is '%s')\n",
958 uss_whoami, uss_PwdLen, uss_Pwd);
959 return (-1);
960 }
961 if (uss_Pwd[0] == '\0') {
962 /*
963 * The user's password has not been provided. Use
964 * the default.
965 */
966 sprintf(uss_Pwd, "%s", uss_DEFAULT_PASSWORD);
967 if (uss_verbose)
968 fprintf(stderr, "%s: Using default password, '%s'\n", uss_whoami,
969 uss_Pwd);
970 } /*Use default password */
971 if ((*a_tp == '\0') || (*a_tp == '\n'))
972 return (0);
973
974 a_tp =
975 uss_common_FieldCp(uss_Server, a_tp, ':', uss_ServerLen, &overflow);
976 if (overflow) {
977 fprintf(stderr, "%s: * Server field too long (max is %d chars)\n",
978 uss_whoami, uss_ServerLen);
979 return (-1);
980 }
981 if ((*a_tp == '\0') || (*a_tp == '\n'))
982 return (0);
983
984 a_tp =
985 uss_common_FieldCp(uss_Partition, a_tp, ':', uss_PartitionLen,
986 &overflow);
987 if (overflow) {
988 fprintf(stderr, "%s: * Partition field too long (max is %d chars)\n",
989 uss_whoami, uss_PartitionLen);
990 return (-1);
991 }
992 if ((*a_tp == '\0') || (*a_tp == '\n'))
993 return (0);
994
995 a_tp =
996 uss_common_FieldCp(uss_MountPoint, a_tp, ':', uss_MountPointLen,
997 &overflow);
998 if (overflow) {
999 fprintf(stderr, "%s: * Mountpoint field too long (max is %d chars)\n",
1000 uss_whoami, uss_MountPointLen);
1001 return (-1);
1002 }
1003 if ((*a_tp == '\0') || (*a_tp == '\n'))
1004 return (0);
1005
1006 a_tp = uss_common_FieldCp(uss_Uid, a_tp, ':', uss_UidLen, &overflow);
1007 if (overflow) {
1008 fprintf(stderr, "%s: * UID field too long (max is %d chars)\n",
1009 uss_whoami, uss_UidLen);
1010 return (-1);
1011 }
1012 uss_DesiredUID = atoi(uss_Uid);
1013 if ((*a_tp == '\0') || (*a_tp == '\n'))
1014 return (0);
1015
1016 for (uss_VarMax = 1; uss_VarMax < 10; uss_VarMax++) {
1017 a_tp =
1018 uss_common_FieldCp(uss_Var[uss_VarMax], a_tp, ':',
1019 uss_MAX_ARG_SIZE, &overflow);
1020 if (overflow) {
1021 fprintf(stderr,
1022 "%s: * Variable %d field too long (max is %d chars)\n",
1023 uss_whoami, uss_VarMax, uss_MAX_ARG_SIZE);
1024 return (-1);
1025 }
1026 if ((*a_tp == '\0') || (*a_tp == '\n'))
1027 return (0);
1028 }
1029
1030 /*
1031 * If there's anything left on the line, we ignore it. Announce
1032 * the bulk add parameters we've parsed or filled in if we're
1033 * being verbose, then go for it.
1034 */
1035 if (uss_verbose) {
1036 fprintf(stderr,
1037 "\nAdding user '%s' ('%s'), password='%s' on server '%s', partition '%s', home directory='%s'",
1038 uss_User, uss_RealName, uss_Pwd,
1039 (uss_Server[0] != '\0' ? uss_Server : "<default>"),
1040 (uss_Partition[0] != '\0' ? uss_Partition : "<default>"),
1041 (uss_MountPoint[0] != '\0' ? uss_MountPoint : "<default>"));
1042 if (uss_DesiredUID)
1043 fprintf(stderr, ", uid preset to %d\n", uss_DesiredUID);
1044 else
1045 fprintf(stderr, ", no preset uid\n");
1046 for (i = 1; i <= uss_VarMax; i++) {
1047 if (uss_Var[i][0] != '\0')
1048 fprintf(stderr, "$%1d='%s' ", i, uss_Var[i]);
1049 }
1050 if (uss_VarMax > 0)
1051 fprintf(stderr, "\n");
1052 }
1053
1054 /*Verbose status of add command */
1055 /*
1056 * Now do the real work.
1057 */
1058 return (DoAdd());
1059
1060 } /*DoBulkPurgeVolumeLine */
1061 #endif /* USS_DONT_HIDE_SOME_FEATURES */
1062 #endif /* USS_FUTURE_FEATURES */
1063
1064 #if USS_FUTURE_FEATURES
1065 #if USS_DONT_HIDE_SOME_FEATURES
1066 /*-----------------------------------------------------------------------
1067 * static DoBulkRestoreLine
1068 *
1069 * Description:
1070 * Process the given bulk add command.
1071 *
1072 * Arguments:
1073 * a_buf : Ptr to the buffer holding the bulk add command.
1074 * a_tp : Ptr to the first char past the opcode.
1075 *
1076 * Returns:
1077 * 0 if everything went well,
1078 * -1 if something went wrong in the function, or
1079 * Lower-level error code if something went wrong below us.
1080 *
1081 * Environment:
1082 * Nothing interesting.
1083 *
1084 * Side Effects:
1085 * As advertised.
1086 *------------------------------------------------------------------------*/
1087
1088 static int
1089 DoBulkRestoreLine(char *a_buf, char *a_tp)
1090 { /*DoBulkRestoreLine */
1091
1092 int i; /*Loop variable */
1093 int overflow; /*Overflow occur on field copy? */
1094
1095 /*
1096 * Pull out all the fields.
1097 */
1098 a_tp = uss_common_FieldCp(uss_User, a_tp, ':', uss_UserLen, &overflow);
1099 if (overflow) {
1100 fprintf(stderr, "%s: * User field too long (max is %d chars)\n",
1101 uss_whoami, uss_UserLen);
1102 return (-1);
1103 }
1104 if ((*a_tp == '\0') || (*a_tp == '\n')) {
1105 fprintf(stderr,
1106 "%s: * The user field must appear in a bulk add command.\n",
1107 uss_whoami);
1108 return (-1);
1109 }
1110
1111 a_tp =
1112 uss_common_FieldCp(uss_RealName, a_tp, ':', uss_RealNameLen,
1113 &overflow);
1114 if (overflow) {
1115 fprintf(stderr, "%s: * Real name field too long (max is %d chars)\n",
1116 uss_whoami, uss_RealNameLen);
1117 return (-1);
1118 }
1119 if (uss_RealName[0] == '\0') {
1120 /*
1121 * The user's real name has not been supplied. As a
1122 * default, we use the account name.
1123 */
1124 sprintf(uss_RealName, "%s", uss_User);
1125 if (uss_verbose)
1126 fprintf(stderr, "%s: Using default real name, '%s'\n", uss_whoami,
1127 uss_User);
1128 }
1129 /*Use default full name */
1130 a_tp = uss_common_FieldCp(uss_Pwd, a_tp, ':', uss_PwdLen, &overflow);
1131 if (overflow) {
1132 fprintf(stderr, "%s: * Password field too long (max is %d chars)\n",
1133 uss_whoami, uss_PwdLen);
1134 return (-1);
1135 }
1136 if (uss_Pwd[0] == '\0') {
1137 /*
1138 * The user's password has not been provided. Use
1139 * the default.
1140 */
1141 sprintf(uss_Pwd, "%s", uss_DEFAULT_PASSWORD);
1142 if (uss_verbose)
1143 fprintf(stderr, "%s: Using default password, '%s'\n", uss_whoami,
1144 uss_Pwd);
1145 } /*Use default password */
1146 if ((*a_tp == '\0') || (*a_tp == '\n'))
1147 return (0);
1148
1149 a_tp =
1150 uss_common_FieldCp(uss_Server, a_tp, ':', uss_ServerLen, &overflow);
1151 if (overflow) {
1152 fprintf(stderr, "%s: * Server field too long (max is %d chars)\n",
1153 uss_whoami, uss_ServerLen);
1154 return (-1);
1155 }
1156 if ((*a_tp == '\0') || (*a_tp == '\n'))
1157 return (0);
1158
1159 a_tp =
1160 uss_common_FieldCp(uss_Partition, a_tp, ':', uss_PartitionLen,
1161 &overflow);
1162 if (overflow) {
1163 fprintf(stderr, "%s: * Partition field too long (max is %d chars)\n",
1164 uss_whoami, uss_PartitionLen);
1165 return (-1);
1166 }
1167 if ((*a_tp == '\0') || (*a_tp == '\n'))
1168 return (0);
1169
1170 a_tp =
1171 uss_common_FieldCp(uss_MountPoint, a_tp, ':', uss_MountPointLen,
1172 &overflow);
1173 if (overflow) {
1174 fprintf(stderr, "%s: * mountpoint field too long (max is %d chars)\n",
1175 uss_whoami, uss_MountPointLen);
1176 return (-1);
1177 }
1178 if ((*a_tp == '\0') || (*a_tp == '\n'))
1179 return (0);
1180
1181 a_tp = uss_common_FieldCp(uss_Uid, a_tp, ':', uss_UidLen, &overflow);
1182 if (overflow) {
1183 fprintf(stderr, "%s: * UID field too long (max is %d chars)\n",
1184 uss_whoami, uss_UidLen);
1185 return (-1);
1186 }
1187 uss_DesiredUID = atoi(uss_Uid);
1188 if ((*a_tp == '\0') || (*a_tp == '\n'))
1189 return (0);
1190
1191 for (uss_VarMax = 1; uss_VarMax < 10; uss_VarMax++) {
1192 a_tp =
1193 uss_common_FieldCp(uss_Var[uss_VarMax], a_tp, ':',
1194 uss_MAX_ARG_SIZE, &overflow);
1195 if (overflow) {
1196 fprintf(stderr,
1197 "%s: * Variable %d field too long (max is %d chars)\n",
1198 uss_whoami, uss_VarMax, uss_MAX_ARG_SIZE);
1199 return (-1);
1200 }
1201 if ((*a_tp == '\0') || (*a_tp == '\n'))
1202 return (0);
1203 }
1204
1205 /*
1206 * If there's anything left on the line, we ignore it. Announce
1207 * the bulk add parameters we've parsed or filled in if we're
1208 * being verbose, then go for it.
1209 */
1210 if (uss_verbose) {
1211 fprintf(stderr,
1212 "\nAdding user '%s' ('%s'), password='%s' on server '%s', partition '%s', home directory='%s'",
1213 uss_User, uss_RealName, uss_Pwd,
1214 (uss_Server[0] != '\0' ? uss_Server : "<default>"),
1215 (uss_Partition[0] != '\0' ? uss_Partition : "<default>"),
1216 (uss_MountPoint[0] != '\0' ? uss_MountPoint : "<default>"));
1217 if (uss_DesiredUID)
1218 fprintf(stderr, ", uid preset to %d\n", uss_DesiredUID);
1219 else
1220 fprintf(stderr, ", no preset uid\n");
1221 for (i = 1; i <= uss_VarMax; i++) {
1222 if (uss_Var[i][0] != '\0')
1223 fprintf(stderr, "$%1d='%s' ", i, uss_Var[i]);
1224 }
1225 if (uss_VarMax > 0)
1226 fprintf(stderr, "\n");
1227 }
1228
1229 /*Verbose status of add command */
1230 /*
1231 * Now do the real work.
1232 */
1233 return (DoRestore());
1234
1235 } /*DoBulkRestoreLine */
1236 #endif /* USS_DONT_HIDE_SOME_FEATURES */
1237 #endif /* USS_FUTURE_FEATURES */
1238
1239
1240 /*-----------------------------------------------------------------------
1241 * static DoBulkExecLine
1242 *
1243 * Description:
1244 * Process the given bulk exec command.
1245 *
1246 * Arguments:
1247 * a_buf : Ptr to the buffer holding the bulk exec command.
1248 * a_tp : Ptr to the first char past the opcode.
1249 *
1250 * Returns:
1251 * 0 if everything went well,
1252 * -1 if something went wrong in the function, or
1253 * Lower-level error code if something went wrong below us.
1254 *
1255 * Environment:
1256 * Nothing interesting.
1257 *
1258 * Side Effects:
1259 * As advertised.
1260 *------------------------------------------------------------------------*/
1261
1262 static int
1263 DoBulkExecLine(char *a_buf, char *a_tp)
1264 { /*DoBulkExecLine */
1265
1266 afs_int32 code; /*Return code */
1267
1268 /*
1269 * Really, uss_procs_Exec does all the work for us!
1270 */
1271 code = uss_procs_Exec(a_tp);
1272 return (code);
1273
1274 } /*DoBulkExecLine */
1275
1276
1277 /*-----------------------------------------------------------------------
1278 * static HandleBulk
1279 *
1280 * Description:
1281 * Process the given bulk command.
1282 *
1283 * Arguments:
1284 * a_as : Ptr to the command line syntax descriptor.
1285 * a_rock : Ptr to the rock passed in.
1286 *
1287 * Returns:
1288 * 0 if everything went well,
1289 * 1 if something went wrong in the function, or
1290 * Lower-level error code if something went wrong below us.
1291 *
1292 * Environment:
1293 * Nothing interesting.
1294 *
1295 * Side Effects:
1296 * As advertised.
1297 *------------------------------------------------------------------------*/
1298 extern int Pipe;
1299 static int
1300 HandleBulk(struct cmd_syndesc *a_as, void *a_rock)
1301 { /*HandleBulk */
1302
1303 #define USS_BULK_CMD_CHARS 128
1304 #define USS_BULK_BUF_CHARS 1024
1305
1306 char cmd[USS_BULK_CMD_CHARS], buf[USS_BULK_BUF_CHARS];
1307 FILE *infile;
1308 char *tp;
1309 int overflow;
1310 int code;
1311
1312 int line_no = 0;
1313 int error = 0;
1314 char tbuf[USS_BULK_BUF_CHARS];
1315
1316 /*
1317 * Open up the bulk file, croak if we can't.
1318 */
1319 if ((infile = fopen(a_as->parms[ABULK_FILE].items->data, "r")) == NULL) {
1320 fprintf(stderr, "%s: * Failed to open input file %s\n", uss_whoami,
1321 a_as->parms[ABULK_FILE].items->data);
1322 return (-1);
1323 }
1324
1325 /*
1326 * Pull out the other fields as passed in by the caller on the
1327 * command line.
1328 */
1329 if (a_as->parms[AUSS_DRYRUN].items)
1330 uss_DryRun = 1;
1331 if (a_as->parms[AUSS_SKIPAUTH].items)
1332 uss_SkipKaserver = 1;
1333 if (a_as->parms[AUSS_OVERWRITE].items)
1334 uss_Overwrite = 1;
1335 if (a_as->parms[AUSS_PIPE].items)
1336 Pipe = 1;
1337 if (a_as->parms[AUSS_ADMIN].items)
1338 strcpy(uss_Administrator, a_as->parms[AUSS_ADMIN].items->data);
1339 else
1340 uss_Administrator[0] = '\0';
1341
1342 if (a_as->parms[AUSS_PWEXPIRES].items) {
1343 uss_BulkExpires = atoi(a_as->parms[AUSS_PWEXPIRES].items->data);
1344 if (uss_BulkExpires < 0 || uss_BulkExpires > 254) {
1345 fprintf(stderr,
1346 "%s: Password Expiration must be in [0..255] days\n",
1347 uss_whoami);
1348 return (-1);
1349 }
1350 } else
1351 uss_BulkExpires = 0;
1352
1353 /*
1354 * Initialize uss_AccountCreator().
1355 */
1356 code = uss_kauth_InitAccountCreator();
1357 if (code)
1358 return (code);
1359
1360 /*
1361 * Process all the lines in the bulk command file.
1362 */
1363 uss_VarMax = 0; /*No uss vars picked up yet */
1364 while (fgets(buf, sizeof(buf), infile) != NULL) {
1365
1366 /* skip blank line */
1367
1368 if (buf[0] == '\n')
1369 continue;
1370
1371 /* After executing the line, print the line and the result */
1372 if (line_no) {
1373 if (error == UNOQUORUM) {
1374 IOMGR_Sleep(1);
1375 }
1376
1377 if (!error)
1378 error = uss_perr;
1379 printf("LINE %d %s %s", line_no, (error ? "FAIL" : "SUCCESS"),
1380 tbuf);
1381 fflush(stdout);
1382 }
1383
1384 /*
1385 * Reset the common variables for each command line
1386 * processed.
1387 */
1388 uss_common_Reset();
1389
1390 strncpy(tbuf, buf, USS_BULK_BUF_CHARS-1);
1391
1392 /*
1393 * First line of file = line 1.
1394 */
1395
1396 ++line_no;
1397
1398 /*
1399 * Get the opcode and act upon it.
1400 */
1401 tp = uss_common_FieldCp(cmd, buf, ' ', USS_BULK_CMD_CHARS, &overflow);
1402 if (overflow) {
1403 fprintf(stderr,
1404 "%s: * Bulk opcode field too long (max is %d chars)\n",
1405 uss_whoami, USS_BULK_CMD_CHARS);
1406
1407 error = -1;
1408 continue;
1409 /*
1410 return(-1);
1411 */
1412 }
1413 if (strcmp(cmd, "add") == 0) {
1414 error = DoBulkAddLine(buf, tp);
1415 continue;
1416 }
1417 if (strcmp(cmd, "delete") == 0) {
1418 error = DoBulkDeleteLine(buf, tp);
1419 continue;
1420 }
1421 if (strcmp(cmd, "delvolume") == 0) {
1422 uss_SaveVolume = 0;
1423 error = 0;
1424 continue;
1425 }
1426 #if USS_FUTURE_FEATURES
1427 #if USS_DONT_HIDE_SOME_FEATURES
1428 if (strcmp(cmd, "purgevolume") == 0) {
1429 error = DoBulkPurgeVolumeLine(buf, tp);
1430 continue;
1431 }
1432 if (strcmp(cmd, "pwdformat") == 0) {
1433 /*Set the password format here */
1434 continue;
1435 }
1436 if (strcmp(cmd, "pwdpath") == 0) {
1437 /*Set the password path here */
1438 continue;
1439 }
1440 if (strcmp(cmd, "restore") == 0) {
1441 error = DoBulkRestoreLine(buf, tp);
1442 continue;
1443 }
1444 #endif /* USS_DONT_HIDE_SOME_FEATURES */
1445 #endif /* USS_FUTURE_FEATURES */
1446 if (strcmp(cmd, "savevolume") == 0) {
1447 /*Set the savevolume flag here */
1448 continue;
1449 }
1450 if (strcmp(cmd, "exec") == 0) {
1451 error = DoBulkExecLine(buf, tp);
1452 continue;
1453 }
1454
1455 /*
1456 * If none of the valid opcodes match, see if the line is either
1457 * a comment of a blank. If so, just ignore it. Otherwise, we
1458 * have a problem.
1459 */
1460 if ((cmd[0] != '#') && (cmd[0] != '\0')) {
1461 fprintf(stderr,
1462 "%s: ** Unrecognized command ('%s') in bulk file\n",
1463 uss_whoami, cmd);
1464
1465 error = -1;
1466 continue;
1467
1468 /*
1469 return(-1);
1470 */
1471 } /*Bad bulk line */
1472 } /*Process a line in the bulk file */
1473
1474 /* Last line. */
1475 if (line_no) {
1476 if (!error)
1477 error = uss_perr;
1478 printf("LINE %d %s %s", line_no, (error ? "FAIL" : "SUCCESS"), tbuf);
1479 fflush(stdout);
1480 }
1481
1482 return (0);
1483 } /*HandleBulk */
1484
1485
1486 /*-----------------------------------------------------------------------
1487 * static AddUser
1488 *
1489 * Description:
1490 * Process the given (non-bulk) add command.
1491 *
1492 * Arguments:
1493 * a_as : Ptr to the command line syntax descriptor.
1494 * a_rock : Ptr to the rock passed in.
1495 *
1496 * Returns:
1497 * 0 if everything went well,
1498 * 1 if something went wrong in the function, or
1499 * Lower-level error code if something went wrong below us.
1500 *
1501 * Environment:
1502 * Nothing interesting.
1503 *
1504 * Side Effects:
1505 * As advertised.
1506 *------------------------------------------------------------------------*/
1507
1508 static int
1509 AddUser(struct cmd_syndesc *a_as, void *a_rock)
1510 { /*AddUser */
1511
1512 int i;
1513 struct cmd_item *ti;
1514 int code;
1515
1516 /*
1517 * Before we do anything else, make sure we initialize the
1518 * global field settings.
1519 */
1520 uss_common_Reset();
1521
1522 /*
1523 * Pull out the fields as passed in by the caller on the command
1524 * line.
1525 */
1526 strcpy(uss_User, a_as->parms[AUP_USER].items->data);
1527 if (a_as->parms[AUP_REALNAME].items)
1528 strcpy(uss_RealName, a_as->parms[AUP_REALNAME].items->data);
1529 else
1530 strcpy(uss_RealName, uss_User);
1531 if (a_as->parms[AUP_PASSWD].items)
1532 strcpy(uss_Pwd, a_as->parms[AUP_PASSWD].items->data);
1533 else
1534 strcpy(uss_Pwd, uss_DEFAULT_PASSWORD);
1535 if (a_as->parms[AUP_SERVER].items)
1536 strcpy(uss_Server, a_as->parms[AUP_SERVER].items->data);
1537 if (a_as->parms[AUP_PART].items)
1538 strcpy(uss_Partition, a_as->parms[AUP_PART].items->data);
1539 if (a_as->parms[AUP_MNTPT].items)
1540 strcpy(uss_MountPoint, a_as->parms[AUP_MNTPT].items->data);
1541 if (a_as->parms[AUP_UID].items)
1542 uss_DesiredUID = atoi(a_as->parms[AUP_UID].items->data);
1543 else
1544 uss_DesiredUID = 0;
1545 if (a_as->parms[AUP_PWEXPIRES].items) {
1546 uss_Expires = atoi(a_as->parms[AUP_PWEXPIRES].items->data);
1547 if (uss_Expires < 0 || uss_Expires > 254) {
1548 fprintf(stderr,
1549 "%s: Password Expiration must be in [0..255] days\n",
1550 uss_whoami);
1551 return (-1);
1552 }
1553 } else
1554 uss_Expires = 0;
1555
1556 if (a_as->parms[AUSS_DRYRUN].items)
1557 uss_DryRun = 1;
1558 if (a_as->parms[AUSS_SKIPAUTH].items)
1559 uss_SkipKaserver = 1;
1560 if (a_as->parms[AUSS_OVERWRITE].items)
1561 uss_Overwrite = 1;
1562 if (a_as->parms[AUSS_ADMIN].items) {
1563 strcpy(uss_Administrator, a_as->parms[AUSS_ADMIN].items->data);
1564 /* fprintf(stderr, "debugging: uss_Administrator set to '%s'\n",
1565 * uss_Administrator); */
1566 } else {
1567 /* fprintf(stderr, "debugging: No administrator value given\n"); */
1568 uss_Administrator[0] = '\0';
1569 }
1570
1571 if (a_as->parms[AUSS_VAR].items) {
1572 for (ti = a_as->parms[AUSS_VAR].items; ti; ti = ti->next) {
1573 i = atoi(ti->data);
1574 if (i < 0 || i > 9 || (i == 0 && *ti->data != '0')) {
1575 fprintf(stderr,
1576 "%s: Bad -var format: must be '0 val0 1 val1 ... 9 val9'\n",
1577 uss_whoami);
1578 return (-1);
1579 }
1580 ti = ti->next;
1581 if (!ti) {
1582 fprintf(stderr,
1583 "%s: -var values must appear in pairs: 'Num val'\n",
1584 uss_whoami);
1585 return (-1);
1586 }
1587 strcpy(uss_Var[i], ti->data);
1588 if (i > uss_VarMax)
1589 uss_VarMax = i;
1590 } /*Remember each VAR item */
1591 }
1592
1593 /*VAR items exist */
1594 /*
1595 * Initialize uss_AccountCreator().
1596 */
1597 code = uss_kauth_InitAccountCreator();
1598 if (code)
1599 return (code);
1600
1601 /*
1602 * Now that the command line arguments are parsed and properly stored,
1603 * go for it!
1604 */
1605 return (DoAdd());
1606
1607 } /*AddUser */
1608
1609
1610 /*-----------------------------------------------------------------------
1611 * static DoAdd
1612 *
1613 * Description:
1614 * Create the desired user account, having parsed the add command
1615 * from either the command line or a bulk file.
1616 *
1617 * Arguments:
1618 * None.
1619 *
1620 * Returns:
1621 * 0 if everything went well,
1622 * 1 if something went wrong in the function, or
1623 * Lower-level error code if something went wrong below us.
1624 *
1625 * Environment:
1626 * All values needed have been put in the common variables.
1627 *
1628 * Side Effects:
1629 * As advertised.
1630 *------------------------------------------------------------------------*/
1631
1632 static int
1633 DoAdd(void)
1634 { /*DoAdd */
1635
1636 int code; /*Return code */
1637
1638 /*
1639 * Make sure the user name is legal.
1640 */
1641 code = uss_kauth_CheckUserName();
1642 if (code)
1643 return (code);
1644
1645 /*
1646 * This time around, we start off assuming the global value of the
1647 * -overwrite flag.
1648 */
1649 uss_OverwriteThisOne = uss_Overwrite;
1650
1651 /*
1652 * Open up the template file before doing any real processing,
1653 * so we can quit early should it not be found.
1654 */
1655 if (uss_yyin == NULL) {
1656 if ((uss_yyin = uss_procs_FindAndOpen(Template)) == NULL) {
1657 fprintf(stderr, "%s: ** Can't open template file '%s'\n",
1658 uss_whoami, Template);
1659 return (-1);
1660 }
1661 uss_yyout = fopen("/dev/null", "w");
1662 } else
1663 rewind(uss_yyin);
1664
1665 /*
1666 * Add the new user to the Protection DB.
1667 */
1668 code = uss_ptserver_AddUser(uss_User, uss_Uid);
1669 if (code) {
1670 fprintf(stderr, "%s: Failed to add user '%s' to the Protection DB\n",
1671 uss_whoami, uss_User);
1672 return (code);
1673 }
1674
1675 /*
1676 * Add the new user to the Authentication DB.
1677 */
1678 code = uss_kauth_AddUser(uss_User, uss_Pwd);
1679 if (code) {
1680 fprintf(stderr, "%s: Can't add user '%s' to the Authentication DB\n",
1681 uss_whoami, uss_User);
1682 return (code);
1683 }
1684
1685 /*
1686 * Process the items covered by the template file.
1687 */
1688 if (yyparse() && (!uss_ignoreFlag))
1689 exit(-1);
1690
1691 /*
1692 * Finally, clean up after ourselves, removing the uss_AccountCreator
1693 * from various of the new user's ACLs.
1694 */
1695 return (uss_acl_CleanUp());
1696
1697 } /*DoAdd */
1698
1699
1700 #if USS_FUTURE_FEATURES
1701 #if USS_DONT_HIDE_SOME_FEATURES
1702 /*-----------------------------------------------------------------------
1703 * static DoRestore
1704 *
1705 * Description:
1706 * Perform the parsed restore command.
1707 *
1708 * Arguments:
1709 * None.
1710 *
1711 * Returns:
1712 * 0 if everything went well,
1713 * 1 if something went wrong in the function, or
1714 * Lower-level error code if something went wrong below us.
1715 *
1716 * Environment:
1717 * All values needed have been put in the common variables.
1718 *
1719 * Side Effects:
1720 * As advertised.
1721 *------------------------------------------------------------------------*/
1722
1723 static int
1724 DoRestore(void)
1725 { /*DoRestore */
1726
1727 return (0);
1728
1729 } /*DoRestore */
1730 #endif /* USS_DONT_HIDE_SOME_FEATURES */
1731 #endif /* USS_FUTURE_FEATURES */
1732
1733
1734 /*-----------------------------------------------------------------------
1735 * static InitETTables
1736 *
1737 * Description:
1738 * Set up the error code tables for the various modules we use.
1739 *
1740 * Arguments:
1741 * None.
1742 *
1743 * Returns:
1744 * Nothing.
1745 *
1746 * Environment:
1747 * Nothing interesting.
1748 *
1749 * Side Effects:
1750 * As advertised.
1751 *------------------------------------------------------------------------*/
1752
1753 void
1754 InitETTables(void)
1755 { /*InitETTables */
1756
1757
1758 /*
1759 * In order to get error code -> error message translations to work,
1760 * we have to initialize all error tables.
1761 */
1762 initialize_CMD_error_table();
1763 initialize_RXK_error_table();
1764 initialize_KTC_error_table();
1765 initialize_KA_error_table();
1766 initialize_ACFG_error_table();
1767 initialize_VL_error_table();
1768 initialize_PT_error_table();
1769 initialize_U_error_table();
1770
1771 } /*InitETTables */
1772
1773
1774 int
1775 osi_audit(void)
1776 {
1777 /* this sucks but it works for now.
1778 */
1779 return 0;
1780 }
1781
1782 #include "AFS_component_version_number.c"
1783
1784 int
1785 main(int argc, char *argv[])
1786 { /*Main routine */
1787
1788 struct cmd_syndesc *cs; /*Command line syntax descriptor */
1789
1790 #ifdef AFS_AIX32_ENV
1791 /*
1792 * The following signal action for AIX is necessary so that in case of a
1793 * crash (i.e. core is generated) we can include the user's data section
1794 * in the core dump. Unfortunately, by default, only a partial core is
1795 * generated which, in many cases, isn't too useful.
1796 */
1797 struct sigaction nsa;
1798
1799 sigemptyset(&nsa.sa_mask);
1800 nsa.sa_handler = SIG_DFL;
1801 nsa.sa_flags = SA_FULLDUMP;
1802 sigaction(SIGABRT, &nsa, NULL);
1803 sigaction(SIGSEGV, &nsa, NULL);
1804 #endif
1805 strcpy(uss_whoami, argv[0]);
1806 uss_yyin = NULL;
1807
1808 uss_fs_InBuff = malloc(USS_FS_MAX_SIZE); /*Cache Manager input buff */
1809 uss_fs_OutBuff = malloc(USS_FS_MAX_SIZE); /*Cache Manager output buff */
1810 if (!uss_fs_InBuff || !uss_fs_OutBuff) {
1811 fprintf(stderr, "%s: Can't malloc in/out buffers\n", uss_whoami);
1812 exit(-1);
1813 }
1814
1815 /* ----------------------------- add ----------------------------- */
1816
1817 cs = cmd_CreateSyntax("add", AddUser, NULL, 0, "create a new user account");
1818 cmd_AddParm(cs, "-user", CMD_SINGLE, 0, "login name");
1819 cmd_AddParm(cs, "-realname", CMD_SINGLE, CMD_OPTIONAL,
1820 "full name in quotes");
1821 cmd_AddParm(cs, "-pass", CMD_SINGLE, CMD_OPTIONAL, "initial password");
1822 /* new parm */
1823 cmd_AddParm(cs, "-pwexpires", CMD_SINGLE, CMD_OPTIONAL,
1824 "password expires in [0..254] days (0 => never)");
1825 cmd_AddParm(cs, "-server", CMD_SINGLE, CMD_OPTIONAL,
1826 "FileServer for home volume");
1827 cmd_AddParm(cs, "-partition", CMD_SINGLE, CMD_OPTIONAL,
1828 "FileServer's disk partition for home volume");
1829 cmd_AddParm(cs, "-mount", CMD_SINGLE, CMD_OPTIONAL,
1830 "home directory mount point");
1831 cmd_AddParm(cs, "-uid", CMD_SINGLE, CMD_OPTIONAL,
1832 "uid to assign the user");
1833 cmd_Seek(cs, AUSS_TEMPLATE);
1834 cmd_AddParm(cs, "-template", CMD_SINGLE, CMD_OPTIONAL,
1835 "pathname of template file");
1836 cmd_AddParm(cs, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose operation");
1837 cmd_AddParm(cs, "-var", CMD_LIST, CMD_OPTIONAL | CMD_EXPANDS,
1838 "auxiliary argument pairs (Num val)");
1839 cmd_AddParm(cs, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1840 cmd_AddParm(cs, "-admin", CMD_SINGLE, CMD_OPTIONAL,
1841 "administrator to authenticate");
1842 cmd_AddParm(cs, "-dryrun", CMD_FLAG, CMD_OPTIONAL,
1843 "list what would be done, don't do it");
1844 cmd_AddParm(cs, "-skipauth", CMD_FLAG, CMD_OPTIONAL,
1845 "ignore all contact with the authentication server (kaserver)");
1846 cmd_AddParm(cs, "-overwrite", CMD_FLAG, CMD_OPTIONAL,
1847 "Overwrite pre-existing files in user home directory tree");
1848
1849
1850 /* ---------------------------- bulk ----------------------------- */
1851
1852 cs = cmd_CreateSyntax("bulk", HandleBulk, NULL, 0, "bulk input mode");
1853 cmd_AddParm(cs, "-file", CMD_SINGLE, 0, "bulk input file");
1854 cmd_Seek(cs, AUSS_TEMPLATE);
1855 cmd_AddParm(cs, "-template", CMD_SINGLE, CMD_OPTIONAL,
1856 "pathname of template file");
1857 cmd_AddParm(cs, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose operation");
1858 cmd_Seek(cs, AUSS_CELL);
1859 cmd_AddParm(cs, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1860 cmd_AddParm(cs, "-admin", CMD_SINGLE, CMD_OPTIONAL,
1861 "administrator to authenticate");
1862 cmd_AddParm(cs, "-dryrun", CMD_FLAG, CMD_OPTIONAL,
1863 "list what would be done, don't do it");
1864 cmd_AddParm(cs, "-skipauth", CMD_FLAG, CMD_OPTIONAL,
1865 "ignore all contact with the authentication server (kaserver)");
1866 cmd_AddParm(cs, "-overwrite", CMD_FLAG, CMD_OPTIONAL,
1867 "Overwrite pre-existing files in user home directory tree");
1868 cmd_Seek(cs, AUSS_PWEXPIRES);
1869 cmd_AddParm(cs, "-pwexpires", CMD_SINGLE, CMD_OPTIONAL,
1870 "password expires in [0..254] days (0 => never)");
1871 cmd_Seek(cs, AUSS_PIPE);
1872 cmd_AddParm(cs, "-pipe", CMD_FLAG, CMD_OPTIONAL,
1873 "don't prompt for passwd; get it from standard input");
1874
1875 /* ---------------------------- delete --------------------------- */
1876
1877 cs = cmd_CreateSyntax("delete", DelUser, NULL, 0, "delete a user account");
1878 cmd_AddParm(cs, "-user", CMD_SINGLE, 0, "login name");
1879 cmd_AddParm(cs, "-mountpoint", CMD_SINGLE, CMD_OPTIONAL,
1880 "mountpoint for user's volume");
1881 #if USS_FUTURE_FEATURES
1882 #if USS_DONT_HIDE_SOME_FEATURES
1883 cmd_AddParm(cs, "-restoredir", CMD_SINGLE, 0,
1884 "directory where restore info is to be placed");
1885 #endif /* USS_DONT_HIDE_SOME_FEATURES */
1886 #endif /* USS_FUTURE_FEATURES */
1887 cmd_AddParm(cs, "-savevolume", CMD_FLAG, CMD_OPTIONAL,
1888 "don't destroy the user's volume");
1889 #if USS_FUTURE_FEATURES
1890 #if USS_DONT_HIDE_SOME_FEATURES
1891 cmd_AddParm(cs, "-pwdpath", CMD_SINGLE, CMD_OPTIONAL,
1892 "pathname to the password file");
1893 cmd_AddParm(cs, "-pwdformat", CMD_SINGLE, CMD_OPTIONAL,
1894 "password entry format");
1895 #endif /* USS_DONT_HIDE_SOME_FEATURES */
1896 #endif /* USS_FUTURE_FEATURES */
1897 cmd_Seek(cs, AUSS_VERBOSE);
1898 cmd_AddParm(cs, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose operation");
1899 cmd_Seek(cs, AUSS_CELL);
1900 cmd_AddParm(cs, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1901 cmd_AddParm(cs, "-admin", CMD_SINGLE, CMD_OPTIONAL,
1902 "administrator to authenticate");
1903 cmd_AddParm(cs, "-dryrun", CMD_FLAG, CMD_OPTIONAL,
1904 "list what would be done, don't do it");
1905 cmd_AddParm(cs, "-skipauth", CMD_FLAG, CMD_OPTIONAL,
1906 "ignore all contact with the authentication server (kaserver)");
1907 #if USS_FUTURE_FEATURES
1908 #if USS_DONT_HIDE_SOME_FEATURES
1909 /* ------------------------- purgevolumes ------------------------ */
1910
1911 cs = cmd_CreateSyntax("purgevolumes", PurgeVolumes, NULL, 0,
1912 "destroy a deleted user's volume");
1913 cmd_AddParm(cs, "-volname", CMD_LIST, CMD_OPTIONAL | CMD_EXPANDS,
1914 "Name(s) of volume(s) to destroy");
1915 cmd_AddParm(cs, "-volfile", CMD_SINGLE, CMD_OPTIONAL,
1916 "pathname to volume purge file");
1917 cmd_Seek(cs, AUSS_VERBOSE);
1918 cmd_AddParm(cs, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose operation");
1919 cmd_Seek(cs, AUSS_CELL);
1920 cmd_AddParm(cs, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1921 cmd_AddParm(cs, "-admin", CMD_SINGLE, CMD_OPTIONAL,
1922 "administrator to authenticate");
1923 cmd_AddParm(cs, "-dryrun", CMD_FLAG, CMD_OPTIONAL,
1924 "list what would be done, don't do it");
1925 cmd_AddParm(cs, "-skipauth", CMD_FLAG, CMD_OPTIONAL,
1926 "ignore all contact with the authentication server (kaserver)");
1927 #endif /* USS_DONT_HIDE_SOME_FEATURES */
1928 #endif /* USS_FUTURE_FEATURES */
1929
1930 #if USS_FUTURE_FEATURES
1931 #if USS_DONT_HIDE_SOME_FEATURES
1932 /* ---------------------------- restore -------------------------- */
1933
1934 cs = cmd_CreateSyntax("restore", RestoreUser, NULL, 0,
1935 "restore a deleted user account");
1936 cmd_AddParm(cs, "-user", CMD_SINGLE, 0, "login name to restore");
1937 cmd_AddParm(cs, "-uid", CMD_SINGLE, 0, "user id number");
1938 cmd_AddParm(cs, "-mount", CMD_SINGLE, 0, "mountpoint for user's volume");
1939 cmd_AddParm(cs, "-volname", CMD_SINGLE, 0, "name of user's volume");
1940 cmd_AddParm(cs, "-realname", CMD_SINGLE, CMD_OPTIONAL,
1941 "user's full name");
1942 cmd_AddParm(cs, "-server", CMD_SINGLE, CMD_OPTIONAL,
1943 "FileServer to host user's volume");
1944 cmd_AddParm(cs, "-partition", CMD_SINGLE, CMD_OPTIONAL,
1945 "FileServer partition to host user's volume");
1946 cmd_AddParm(cs, "-pwdpath", CMD_SINGLE, CMD_OPTIONAL,
1947 "pathname to the password file");
1948 cmd_AddParm(cs, "-pwdformat", CMD_SINGLE, CMD_OPTIONAL,
1949 "password entry format");
1950 cmd_Seek(cs, AUSS_VERBOSE);
1951 cmd_AddParm(cs, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose operation");
1952 cmd_Seek(cs, AUSS_CELL);
1953 cmd_AddParm(cs, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1954 cmd_AddParm(cs, "-admin", CMD_SINGLE, CMD_OPTIONAL,
1955 "administrator to authenticate");
1956 cmd_AddParm(cs, "-dryrun", CMD_FLAG, CMD_OPTIONAL,
1957 "list what would be done, don't do it");
1958 cmd_AddParm(cs, "-skipauth", CMD_FLAG, CMD_OPTIONAL,
1959 "ignore all contact with the authentication server (kaserver)");
1960 #endif /* USS_DONT_HIDE_SOME_FEATURES */
1961 #endif /* USS_FUTURE_FEATURES */
1962
1963 /*
1964 * Set up all the error code translation tables, initialize the
1965 * command variables, and set up to parse the common command line
1966 * parameters.
1967 */
1968 InitETTables();
1969 uss_common_Init();
1970 cmd_SetBeforeProc(GetCommon, NULL);
1971
1972 /*
1973 * Execute the parsed command.
1974 */
1975 cmd_Dispatch(argc, argv);
1976 if (doUnlog) {
1977 uss_fs_UnlogToken(uss_Cell);
1978 }
1979 return 0;
1980 } /*Main routine */