rpasswd.c

Go to the documentation of this file.
00001 /* @(#)root/srputils:$Id: rpasswd.c 20882 2007-11-19 11:31:26Z rdm $ */
00002 /*
00003  * Create a private SRP passwd file.
00004  */
00005 
00006 #include <sys/types.h>
00007 #include <time.h>
00008 #include <stdio.h>
00009 #include <fcntl.h>
00010 #include <unistd.h>
00011 #include <stdlib.h>
00012 #include <pwd.h>
00013 #include <string.h>
00014 
00015 #ifndef P_
00016 #if __STDC__
00017 #define P_(x) x
00018 #else
00019 #define P_(x) ()
00020 #endif
00021 #endif
00022 #define STRFCPY(A,B) \
00023         (strncpy((A), (B), sizeof(A) - 1), (A)[sizeof(A) - 1] = '\0')
00024 extern int obscure P_((const char *, const char *, const struct passwd *));
00025 extern char *Basename P_((char *str));
00026 extern struct passwd *get_my_pwent P_((void));
00027 extern char *xstrdup P_((const char *str));
00028 
00029 #include "pwauth.h"
00030 #include "pwio.h"
00031 #include "getdef.h"
00032 
00033 
00034 /* EPS STUFF */
00035 #include "t_pwd.h"
00036 static int do_update_eps = 0;
00037 struct t_pw eps_passwd;
00038 
00039 /*
00040  * Global variables
00041  */
00042 
00043 static char *name;              /* The name of user whose password is being changed */
00044 static char *myname;            /* The current user's name */
00045 static char *Prog;              /* Program name */
00046 
00047 static char r_tconf[256];       /* -c config file */
00048 static char r_passwd[256];      /* -p passwd file */
00049 
00050 /*
00051  * External identifiers
00052  */
00053 
00054 extern char *crypt_make_salt();
00055 #if !defined(__GLIBC__)
00056 extern char *l64a();
00057 #endif
00058 
00059 extern int optind;              /* Index into argv[] for current option */
00060 extern char *optarg;            /* Pointer to current option value */
00061 
00062 
00063 #define SROOTDCONF ".srootdpass.conf"
00064 #define SROOTDPASS ".srootdpass"
00065 
00066 /*
00067  * #defines for messages.  This facilities foreign language conversion
00068  * since all messages are defined right here.
00069  */
00070 #define USAGE "usage: %s [ -c config ] [ -p passwd ] [ name ]\n"
00071 #define NEWPASSMSG \
00072 "Enter the new password (minimum of %d, maximum of %d characters)\n\
00073 Please use a combination of upper and lower case letters and numbers.\n"
00074 #define NEWPASS "New password:"
00075 #define NEWPASS2 "Re-enter new password:"
00076 #define NOMATCH "They don't match; try again.\n"
00077 
00078 #define EPSFAIL "Unable to update EPS password.\n"
00079 #define NOEPSCONF "Warning: configuration file missing; please run 'tconf'\n"
00080 
00081 #define WHOAREYOU "%s: Cannot determine your user name.\n"
00082 #define UNKUSER "%s: Unknown user %s\n"
00083 #define UNCHANGED "The password for %s is unchanged.\n"
00084 
00085 #define PASSWARN \
00086         "\nWarning: weak password (enter it again to use it anyway).\n"
00087 
00088 /*
00089  * usage - print command usage and exit
00090  */
00091 
00092 static void usage(int status)
00093 {
00094    fprintf(stderr, USAGE, Prog);
00095    exit(status);
00096 }
00097 
00098 
00099 /*
00100  * new_password - validate old password and replace with new
00101  */
00102 
00103 static int new_password(const struct passwd *pw)
00104 {
00105    char clear[128];             /* Pointer to clear text */
00106    char *cp;                    /* Pointer to getpass() response */
00107    char orig[128];              /* Original password */
00108    char pass[128];              /* New password */
00109    int i;                       /* Counter for retries */
00110    int warned;
00111 
00112    /*
00113     * Get the new password.  The user is prompted for the new password
00114     * and has five tries to get it right.  The password will be tested
00115     * for strength, unless it is the root user.  This provides an escape
00116     * for initial login passwords.
00117     */
00118 
00119    warned = 0;
00120    for (i = getdef_num("PASS_CHANGE_TRIES", 5); i > 0; i--) {
00121       t_getpass(clear, 128, NEWPASS);
00122       cp = clear;
00123       if (!cp) {
00124          bzero(orig, sizeof orig);
00125          return -1;
00126       }
00127       if (warned && strcmp(pass, cp) != 0)
00128          warned = 0;
00129       STRFCPY(pass, cp);
00130       bzero(cp, strlen(cp));
00131 
00132       if (!warned && !obscure(orig, pass, pw)) {
00133          printf(PASSWARN);
00134          warned++;
00135          continue;
00136       }
00137       if (!(cp = getpass(NEWPASS2))) {
00138          bzero(orig, sizeof orig);
00139          return -1;
00140       }
00141       if (strcmp(cp, pass))
00142          fprintf(stderr, NOMATCH);
00143       else {
00144          bzero(cp, strlen(cp));
00145          break;
00146       }
00147    }
00148    bzero(orig, sizeof orig);
00149 
00150    if (i == 0) {
00151       bzero(pass, sizeof pass);
00152       return -1;
00153    }
00154 
00155    /*
00156     * Encrypt the password, then wipe the cleartext password.
00157     */
00158 
00159    /* EPS STUFF */
00160    {
00161       struct t_conf *tc;
00162       struct t_confent *tcent;
00163 
00164       if ((tc = t_openconfbyname(r_tconf)) == NULL ||
00165           (tcent = t_getconflast(tc)) == NULL) {
00166          fprintf(stderr, NOEPSCONF);
00167          do_update_eps = 0;
00168       } else {
00169          do_update_eps = 1;
00170          t_makepwent(&eps_passwd, name, pass, NULL, tcent);
00171       }
00172 
00173       if (tc)
00174          t_closeconf(tc);
00175    }
00176 
00177    bzero(pass, sizeof pass);
00178 
00179    return 0;
00180 }
00181 
00182 
00183 /*
00184  * rpasswd - change a user's password file information
00185  *
00186  *      This command controls the password file and commands which are
00187  *      used to modify it.
00188  *
00189  *      The valid options are
00190  *
00191  *      -c      config file name (default $HOME/.srootdpass.conf)
00192  *      -p      passwd file name (default $HOME/.srootdpass)
00193  *
00194  *      Exit status:
00195  *      0 - success
00196  *      1 - permission denied
00197  *      2 - invalid combination of options
00198  *      3 - unexpected failure, password file unchanged
00199  *      5 - password file busy, try again later
00200  *      6 - invalid argument to option
00201  */
00202 
00203 int main(int argc, char **argv)
00204 {
00205    int flag;                    /* Current option to process                                                                                                                                                                                                                                    */
00206    const struct passwd *pw;     /* Password file entry for user      */
00207 
00208    /*
00209     * Get the program name.  The program name is used as a
00210     * prefix to most error messages.
00211     */
00212 
00213    Prog = Basename(argv[0]);
00214 
00215    sprintf(r_tconf, "%s/%s", getenv("HOME"), SROOTDCONF);
00216    sprintf(r_passwd, "%s/%s", getenv("HOME"), SROOTDPASS);
00217 
00218    /*
00219     * The remaining arguments will be processed one by one and
00220     * executed by this command.  The name is the last argument
00221     * if it does not begin with a "-", otherwise the name is
00222     * determined from the environment and must agree with the
00223     * real UID.  Also, the UID will be checked for any commands
00224     * which are restricted to root only.
00225     */
00226 
00227    while ((flag = getopt(argc, argv, "c:p:")) != EOF) {
00228 
00229       switch (flag) {
00230 
00231       case 'c':
00232          STRFCPY(r_tconf, optarg);
00233          printf("r_tconf: %s\n", r_tconf);
00234          break;
00235       case 'p':
00236          STRFCPY(r_passwd, optarg);
00237          printf("r_passwd: %s\n", r_passwd);
00238          break;
00239       default:
00240          usage(6);
00241       }
00242    }
00243 
00244    /*
00245     * Now I have to get the user name.  The name will be gotten
00246     * from the command line if possible.  Otherwise it is figured
00247     * out from the environment.
00248     */
00249 
00250    pw = get_my_pwent();
00251    if (!pw) {
00252       fprintf(stderr, WHOAREYOU, Prog);
00253       exit(1);
00254    }
00255    myname = xstrdup(pw->pw_name);
00256    if (optind < argc)
00257       name = argv[optind];
00258    else
00259       name = myname;
00260 
00261    /*
00262     * Let the user know whose password is being changed.
00263     */
00264    if (new_password(pw)) {
00265       fprintf(stderr, UNCHANGED, name);
00266       exit(1);
00267    }
00268 
00269 /* EPS STUFF */
00270 
00271    if (do_update_eps) {
00272       FILE *passfp;
00273 
00274       /* try and see if the file is there, else create it */
00275 
00276       if ((passfp = fopen(r_passwd, "r+")) == NULL)
00277          creat(r_passwd, 0400);
00278       else
00279          fclose(passfp);
00280 
00281       if (t_changepw(r_passwd, &(eps_passwd.pebuf)) < 0)
00282          fprintf(stderr, EPSFAIL);
00283 
00284    } else
00285       fprintf(stderr, EPSFAIL);
00286 
00287    exit(0);
00288 }

Generated on Tue Jul 5 14:46:13 2011 for ROOT_528-00b_version by  doxygen 1.5.1