cvs-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Cvs-dev] Re: cvs-passwd patch


From: Mark D. Baushke
Subject: [Cvs-dev] Re: cvs-passwd patch
Date: Fri, 20 Oct 2006 00:21:17 -0700

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Prasad,

P J P <address@hidden> writes:

> 
>    Hello Mark, how are you doing? :)

I am too busy. :-(

Message received. The diff looks 'funny' in some places with extra
whitespace possibly added by the -a option to diff. I am not certain if
patch will deal with it properly or not. As I said, I won't have time
to look at this stuff until mid-November due to a crunch at work.
 
> I've made the changes, you suggested. And the patch for the same is
> included below. After making these changes, the problem is with the
> user-authentication, that's after call to start_server() and at the
> connect_to_pserver().

I do not understand. If you have done a start_server(), then you have
already authenticated the current user. So, if the password to be
changed is for the current user, then there should be no conflict...
(well, in theory it is possible that the :ext: method might use a
username that is not the same as the username they were assigned for
:pserver: use in which case they are out of luck unless their :ext: user
is a cvs administrator).

If you are a local user, then the username associated with the current
process is the one that you will be wanting to use in the CVSROOT/passwd
file.

> Here, I need a mechanism, similar to open_connection_to_server(),
> which is called by start_server() to perform the user-authentication,
> as per the protocol(method) used. But, I'm not sure, if I could do the
> same call instead of connect_to_pserver(). Could you please tell me,
> how could I support the various methods used by cvs. Also please have
> a look at this
> patch below

Comments inline below. Look for MDB:

I have not attemptd to patch it into the sources due to lack of time.

> 
> 
> -----------------------------x cut here x--------------------------------
> 
> diff -Naur ccvs-2006-09-25/src/main.c ccvs-2006-09-25.new/src/main.c
> --- ccvs-2006-09-25/src/main.c        2006-05-17 20:54:30.000000000 +0530
> +++ ccvs-2006-09-25.new/src/main.c    2006-10-20 10:19:50.000000000 +0530
> @@ -30,6 +30,7 @@
>   /* CVS Headers.  */
>   #include "command_line_opt.h"
>   #include "gpg.h"
> +#include "passwd.h"
>   #include "sign.h"
>   #include "verify.h"

MDB:
The other #include lines are left justified in the main.c I have and yet
the diff looks like it believes they are indended by a space. This is
weird.

> 
> @@ -177,6 +178,7 @@
>   #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && 
> defined(SERVER_SUPPORT)
>       { "pserver",  NULL,       NULL,        server,    
> CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, /* placeholder */
>   #endif
> +    { "passwd",        "password", "setpass",   passwd,    
> CVS_CMD_MODIFIES_REPOSITORY },
>       { "rannotate","rann",     "ra",        annotate,  0 },
>       { "rdiff",    "patch",    "pa",        patch,     0 },
>       { "release",  "re",       "rel",       release,   
> CVS_CMD_MODIFIES_REPOSITORY },
> @@ -269,6 +271,7 @@
>       "        logout       Removes entry in .cvspass for remote 
> repository\n",
>   #endif /* AUTH_CLIENT_SUPPORT */
>       "        ls           List files available from CVS\n",
> +    "        passwd       Change your cvs password\n"
>   #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && 
> defined(SERVER_SUPPORT)
>       "        pserver      Password server mode\n",
>   #endif

MDB:
The above hunk is oddly indented.

> diff -Naur ccvs-2006-09-25/src/passwd.c ccvs-2006-09-25.new/src/passwd.c
> --- ccvs-2006-09-25/src/passwd.c      1970-01-01 05:30:00.000000000 +0530
> +++ ccvs-2006-09-25.new/src/passwd.c  2006-10-20 10:45:59.000000000 +0530
> @@ -0,0 +1,583 @@
> +/*
> + * passwd.c: this file is part of the passwd patch for cvs-1.12.13.
> + * Author: PJP <address@hidden>
> + *
> + * Copyright (C) 2006 The Free Software Foundation, Inc.
> + *
> + * Portions Copyright (C) 2006, Prasad J Pandit.
> + *
> + * You may distribute under the terms of the GNU General Public License
> + * as specified in the README file that comes with the CVS source 
> distribution.
> + *
> + * passwd patch for cvs-1.12.13 is ment to add a 'cvs passwd' command to cvs.
> + * This is to facilitate user to change her cvs password from client side 
> using
> + * cvs command line interface.
> + *
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#   include <config.h>
> +#endif
> +
> +#include "md5.h"
> +#include "passwd.h"
> +#include "getline.h"
> +#include "cvs.h"
> +
> +#ifdef CVS_ADMIN_GROUP
> +#   include <grp.h>
> +#endif
> +
> +# if !HAVE_DECL_FLOCKFILE
> +#  undef flockfile
> +#  define flockfile(x) ((void) 0)
> +# endif
> +# if !HAVE_DECL_FUNLOCKFILE
> +#  undef funlockfile
> +#  define funlockfile(x) ((void) 0)
> +# endif
> +
> +static void init_pass (void);
> +static void exit_pass (void);
> +static void read_pass (FILE *);
> +static void write_pass (FILE *);
> +static void insert (const char *);
> +static void generate_salt (char *);
> +static char *read_new_passwd (void);
> +static char *encrypt_pass (const char *);
> +static void alias (const char *, const char *);
> +static int  gettok (const char *, char, char **);
> +static void change_pass (const char *, const char *);
> +
> +enum op_mode { PASSWD = 0, ADD = 1, DISABLE = 2,
> +               DELETE = 4, ALIAS = 8, RALIAS = 16 };
> +static enum op_mode mode;
> +static bool do_encrypt = false, tokset = false;
> +static const char pass_file[] = "/CVSROOT/passwd";
> +
> +static List *pass_list;         /* password record list */
> +static char *rusr, *dpass;      /* remote system user, domain password */
> +static char *cmdname;
> +static char salt_set[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
> +                         "abcdefghijklmnopqrstuvwxyz";
> + +

MDB:
This line above looks weird... Adding a '+' to an empty line?

> +static const char *const passwd_usage[] =
> +{
> +    "Usage: %s %s [-a] [-D domain] [-e] [-r real_user] [-R] [-x] [-X]"\
> +    " [username]\n",
> +    "   -a      add user\n",
> +    "   -D      use domain password (Win32 only)\n",
> +    "   -e      enable local encrypt\n",
> +    "   -r      alias to real system user\n",
> +    "   -R      remove alias to real system user\n",
> +    "   -x      disable user\n",
> +    "   -X      delete user\n",
> +    "(Specify the --help global option for a list of other help options)\n",
> +    NULL
> +};
> +
> +
> +/* check_option: check the command line options */
> +static int
> +check_option (int argc, char *argv[])
> +{
> +    int c = 0;
> +
> +    if (argc < 1)
> +        usage (passwd_usage);
> +
> +    mode = PASSWD;
> +    opterr = optind = 0;
> +    do_encrypt = tokset = false;
> +    while ((c = getopt (argc, argv, "+aD:er:RxX")) != -1)
> +    {
> +        switch (c)
> +        {
> +        case 'a':   /* add user */
> +            mode |= ADD;
> +            break;
> +
> +        case 'D':   /* use domain password */
> +            if (dpass)
> +                free (dpass);
> +            dpass = xstrdup (optarg);
> +            break;
> +
> +        case 'e':   /* do local encrypt */
> +            do_encrypt = true;
> +            break;
> +
> +        case 'r':   /* (remote) real system user */
> +            if (rusr)
> +                free (rusr);
> +            rusr = xstrdup (optarg);
> +            mode |= ALIAS;
> +            break;
> +
> +        case 'R':   /* remove alias */
> +            mode |= RALIAS;
> +            break;
> +
> +        case 'x':   /* disable user */
> +            mode |= DISABLE;
> +            break;
> +
> +        case 'X':   /* delete user */
> +            mode |= DELETE;
> +            break;
> +
> +        default:
> +            error (0, 0, "invalid option");
> +            usage (passwd_usage);
> +        }
> +    }
> +
> +    return optind;
> +}
> + +

MDB:
Weird line above.

> +/*
> + * passwd: This is the `main' function called for both, the cvs-client and 
> the
> + * cvs-server. As a client, it is supposed to read new password from a user
> + * and pass it on to cvs-server. And as a server, to receive username,
> + * password, and other credentials from cvs-client and update the
> + * CVSROOT/passwd file appropriately. It receives the user credentials as
> + * command line arguments in the following format
> + * cvs server passwd [-a] [-D domain] [-e] [-r user] [-R] [-x] [-X]
> + *                   [username] [passwd]
> + */
> +int
> +passwd (int argc, char *argv[])
> +{
> +    Node *tmp = NULL;
> +    int n = 0, ret = 0;
> +    char *key = NULL, *msg = NULL, *usr = NULL, *pass = NULL;
> +
> +    cmdname = argv[0];
> +    n = check_option (argc, argv);
> +    argc -= n;
> +    argv += n;
> + +#ifdef CLIENT_SUPPORT

MDB:
Weird line above.

> +    if (current_parsed_root && current_parsed_root->isremote)
> +    {                               /* cvs client */
> +        usr = (argc > 0) ? argv[0] : current_parsed_root->username;
> +
> +        start_server ();
> +
> +        if (!supported_request ("passwd"))
> +            error (1, 0, "server does not support `%s'", cmdname);
> +        if (!usr && (mode & ADD || mode & DISABLE || mode & DELETE
> +                    || mode & ALIAS || mode & RALIAS))
> +            error (1, 0, "this option requires argument [username]");
> +
> +        if (mode & ADD)
> +            send_arg ("-a");        /* add user */
> +        if (dpass)
> +        {
> +            option_with_arg ("-D", dpass);
> +            free (dpass);
> +            dpass = NULL;
> +        }
> +        if (do_encrypt)
> +        {
> +            if (!supported_request ("passwd-e"))
> +                error (1, 0, "server does not support `-e' option");
> +            send_arg ("-e");
> +        }
> +        if (mode & ALIAS)
> +        {
> +            option_with_arg ("-r", rusr);   /* make alias */
> +            free (rusr);
> +            rusr = NULL;
> +        }
> +        if (mode & RALIAS)
> +            send_arg ("-R");        /* remove alias */
> +        if (mode & DISABLE)
> +            send_arg ("-x");        /* disable user */
> +        if (mode & DELETE)
> +            send_arg ("-X");        /* delete user */
> +        if (!mode)
> +        {                           /* change password */
> +            printf ("Changing password for `%s'\n", usr);
> +            key = getpass ("(current) CVS password: ");
> +            if (!key)
> +                error (1, errno, "failed to read password");
> +            current_parsed_root->password = xstrdup (key);
> +            connect_to_pserver (current_parsed_root, NULL, NULL, 1, 0);

MDB:
If the current user is the same as the authenticated user, then this
step (connect_to_pserver) should not be required.

> +
> +            if (!(pass = read_new_passwd ()))
> +                return -1;
> +            if (strlen (pass) > MAX_LEN)    /* MAX_LEN = 128 */
> +                error (0, 0, "warning: password too long");
> +            if (do_encrypt)
> +                pass = encrypt_pass (pass);
> +            msg = scramble (pass);
> +            free (pass);
> +            pass = msg;
> +        }
> +        if (usr)
> +            send_arg (usr);
> +        else
> +            send_arg ("*");
> +        if (pass)
> +            send_arg (pass);
> +        send_to_server ("passwd\012", 0);
> +        ret = get_responses_and_close ();
> +    }
> +    if (pass) free (pass);
> +    if (current_parsed_root->password)
> +    {
> +        free (current_parsed_root->password);
> +        current_parsed_root->password = NULL;
> +    }
> +#endif
> + +

MDB:
Another Weird line which would add a ' +' line to the file... :-(

> +#ifdef SERVER_SUPPORT
> +    if (server_active)
> +    {                               /* cvs server */
> +        if (!argc)
> +            error (1, 0, "username missing");
> +        usr = strcmp(argv[0], "*") ? argv[0] : CVS_Username;
> +
> +        if ((mode & ADD || mode & ALIAS || mode & RALIAS || mode & DISABLE
> +            || mode & DELETE) && !is_admin ())
> +            error (1, 0, "only cvs admin can do that: permission denied!");
> +        if (!strcmp (argv[0], CVS_Username)
> +            && (mode & DISABLE || mode & DELETE))
> +            error (1, 0, "it's a suicide: operation abandoned!");
> +
> +        init_pass ();
> +        if (mode & ADD)
> +        {                           /* -a add user */
> +            tmp = findnode (pass_list, usr);
> +            if (tmp)
> +                error (1, 0, "name `%s' is not unique", usr);
> +            key = Xasprintf ("%s::\n", usr);
> +            insert (key);
> +        }
> +        if (dpass)
> +        {
> +            free (dpass);
> +            dpass = NULL;
> +            error (1, 0, "option `-D domain' is not supported by server");
> +        }
> +        if (mode & ALIAS)
> +        {
> +            alias (usr, rusr);      /* -r make alias */
> +            free (rusr);
> +            rusr = NULL;
> +        }
> +        if (mode & RALIAS)
> +            alias (usr, "");        /* -R remove alias */
> +        if (mode & DISABLE)
> +            change_pass (usr, "#DISABLED#");  /* -x disable user */
> +        if (mode & DELETE)
> +        {
> +            tmp = findnode (pass_list, usr);
> +            delnode (tmp);          /* -X delete user */
> +        }
> +        if (!mode)
> +        {                           /* change password */
> +            if (strcmp (usr, CVS_Username) && !is_admin ())
> +                error (1, 0, "only cvs admin can do that: permission 
> denied!");
> +            if (argc < 2)
> +                error (1, 0, "password missing");
> +            key = descramble (argv[1]);
> +            pass = (do_encrypt == false) ? encrypt_pass (key) : key;
> +            change_pass (usr, pass);
> +        }
> +        exit_pass ();
> +    }
> +#endif

MDB: 
You are not handling hte case of a user using a non-client/server
method. You may wish to revisit the CVSNT passwd.cpp file for control
flow.

> +
> +    return ret;
> +}
> + +

MDB:
Weird line above.

> +/* init_pass: initialize password record list by reading it from file  */
> +static void
> +init_pass (void)
> +{
> +    FILE *fpass = NULL;
> +    char *fname = NULL;
> +
> +    pass_list = getlist ();
> +    fname = Xasprintf ("%s%s", current_parsed_root->directory, pass_file);
> +    if ((fpass = fopen (fname, "r")) == NULL)
> +        error (1, errno, "could not open: `%s'", fname);
> +    flockfile (fpass); /* acquire exclussive lock on CVSROOT/passwd file */
> +    read_pass (fpass);
> +    funlockfile (fpass);
> +    if (fclose (fpass) != 0)
> +        error (1, errno, "could not close: `%s'", fname);
> +
> +    free (fname);
> +}
> +
> +
> +/* exit_pass: write password list to the file and release the list */
> +static void
> +exit_pass (void)
> +{
> +    FILE *fpass = NULL;
> +    char *fname = NULL;
> +
> +    fname = Xasprintf ("%s%s", current_parsed_root->directory, pass_file);
> +    if ((fpass = fopen (fname, "w")) == NULL)
> +        error (1, errno, "could not open: `%s'", fname);
> +    flockfile (fpass); /* acquire exclussive lock on CVSROOT/passwd file */
> +    write_pass (fpass);
> +    funlockfile (fpass);
> +    if (fclose (fpass) != 0)
> +        error (1, errno, "could not close: `%s'", fname);
> +
> +    dellist (&pass_list);
> +    free (fname);
> +}
> +
> +
> +/* encrypt_pass: encrypt the given password using md5 based algorithm */
> +static char *
> +encrypt_pass (const char *pass)
> +{
> +    char *ret = NULL, salt[SALTSIZE];
> +
> +    assert (pass != NULL);
> +
> +    generate_salt (salt);
> +    if (!(ret = crypt (pass, salt)))
> +        error (1, errno, "encryption failed");
> +
> +    return ret;
> +}
> + +

MDB:
Weird line above. :-(

> +/*
> + * generate_salt: generate an 11 character salt, to be used by crypt(3) for
> + * encryption purpose
> + */
> +static void
> +generate_salt(char *psalt)
> +{
> +#define DIV  64
> +    int i = 0;
> +    time_t tt;
> +
> +    assert (psalt != NULL);
> +
> +    tt = time (&tt);
> +    srand (tt * getpid ());
> +    psalt[i++] = '$';
> +    psalt[i++] = '1';
> +    psalt[i++] = '$';
> +    while (i < SALTSIZE)
> +        psalt[i++] = salt_set[(rand () % DIV)];
> +    psalt[i - 1] = '\0';
> +}
> +
> +
> +/* read_new_passwd: read new password from user    */
> +static char *
> +read_new_passwd (void)
> +{
> +#define TRY_CNT    3
> +#define MIN_LEN    6
> +    short flag = 0, cnt = 0;
> +    char *pass = NULL, *cpass = NULL;
> +
> +    while ((!flag) && (cnt++ < TRY_CNT))
> +    {
> +        pass = getpass ("New CVS password: ");
> +        if (!pass)
> +            error (1, errno, "failed to read password");
> +        if (strlen (pass) < MIN_LEN)
> +        {
> +            error (0, 0, "password too short");
> +            free (pass);
> +            pass = NULL;
> +            continue;
> +        }
> +        pass = xstrdup (pass);
> +        cpass = getpass ("Retype new CVS password: ");
> +        if (!cpass)
> +            error (1, errno, "failed to read password");
> +        if ((strlen (pass) == strlen (cpass)) && (!strcmp (pass, cpass)))
> +            flag = 1;
> +        else
> +        {
> +            error (0, 0, "passwords do not match");
> +            free (pass);
> +            pass = NULL;
> +        }
> +    }
> +    if (!flag && !pass)
> +    {
> +        free (pass);
> +        pass = NULL;
> +    }
> +
> +    return pass;
> +}
> + +
> +/*
> + * change_pass: change the user password in password list created by
> + * read_pass
> + */
> +static void
> +change_pass (const char *usr, const char *pass)
> +{
> +    int n = -1;
> +    Node *tmp = NULL;
> +    char *lusr = NULL, *rec = NULL;
> +
> +    assert (usr != NULL);
> +    assert (pass != NULL);
> +
> +    tmp = findnode (pass_list, usr);
> +    if (!tmp)
> +        error (1, 0, "user `%s' not found", usr);
> +
> +    /*
> +     * tmp->data is of the form...
> +     * username[:password[:mapped local username]]
> +     */
> +    n = gettok (tmp->data, ':', &lusr);
> +    free (lusr);
> +    lusr = NULL;          /* skip username */
> +
> +    n = (n != 0) ? gettok (tmp->data, ':', &lusr) : 0;
> +    free (lusr);
> +    lusr = NULL;          /* skip password */
> +
> +    /* get mapped local username */
> +    n = (n != 0) ? gettok (tmp->data, ':', &lusr) : 0;
> +    if (lusr != NULL)
> +    {
> +        rec = Xasprintf ("%s:%s:%s\n", usr, pass, lusr);
> +        free (lusr);
> +    }
> +    else
> +        rec = Xasprintf ("%s:%s\n", usr, pass);
> +
> +    free (tmp->data);
> +    tmp->data = rec;
> +    tokset = true;
> +}
> + +

MDB:
Weird line above.

> +/* remove_alias: remove the real system user alias of the given cvs user */
> +static void
> +alias (const char *usr, const char *als)
> +{
> +    int n = -1;
> +    Node *tmp = NULL;
> +    char *pass = NULL, *rec = NULL;
> +
> +    assert (usr != NULL);
> +    assert (als != NULL);
> +
> +    tmp = findnode (pass_list, usr);
> +    if (!tmp)
> +        error (1, 0, "user `%s' not found", usr);
> +    n = gettok (tmp->data, ':', &pass);
> +    free (pass);
> +    pass = NULL;           /* skip username */
> +    n = (n != 0) ? gettok (tmp->data, ':', &pass) : 0;
> +    n = (n != 0) ? gettok (tmp->data, ':', &rec) : 0;
> +    free (rec);
> +    rec = NULL;             /* skip alias */
> +    rec = Xasprintf ("%s:%s:%s\n", usr, (pass != NULL) ? pass : "", als);
> +    free (tmp->data);
> +    tmp->data = rec;
> +    tokset = true;
> +
> +    if (pass)
> +        free (pass);
> +}
> +
> +
> +/*
> + * gettok: returns a token into 'ret', from given string 's', comprising of
> + * characters up to next occurrence of 'delim' character in 's'. also returns
> + * an integer value greater than zero(0) when more token are available, and
> + * of zero(0) when an end of string 's' is reached.
> + */
> +static int
> +gettok (const char *s, char delim, char **ret)
> +{
> +    int j = 0;
> +    char buf[BUFLEN];   /* BUFLEN = 512 */
> +    static int i = 0;
> +
> +    if (tokset) i = 0;
> +    memset (buf, 0, BUFLEN);
> +    *ret = NULL;
> +    while ((s[i] != delim) && (s[i] != '\0') && (j < BUFLEN - 1))
> +        buf[j++] = s[i++];
> +    if (buf[j - 1] == '\n')
> +        buf[j - 1] = '\0';
> +    buf[j] = '\0';
> +    if (buf[0] != '\n')
> +        *ret = xstrdup (buf);
> +    (s[i] == '\0') ? i = 0 : i++;
> +    tokset = false;
> +
> +    return i;
> +}
> + +

MDB:
Weird line above.

> +/*
> + * read_pass: reads the CVSROOT/passwd file and build a linked list of
> + * records.
> + */
> +static void
> +read_pass (FILE *fp)
> +{
> +    size_t len = 0;
> +    char *buf = NULL, *str = NULL;
> +
> +    assert (fp != NULL);
> +
> +    while (getline (&buf, &len, fp) > 0)
> +    {
> +        str = xstrdup (buf);
> +        insert (str);
> +        free (buf);
> +        buf = NULL;
> +    }
> +}
> +
> +
> +/* write_pass: write all user credentials to CVSROOT/passwd file */
> +static void
> +write_pass (FILE *fp)
> +{
> +    Node *i = NULL, *head = pass_list->list;
> +
> +    assert (fp != NULL);
> +
> +    for (i = head->next; i != head; i = i->next)
> +        fputs (i->data, fp);
> +}
> +
> +
> +/* insert: insert new rerord in password list    */
> +static void
> +insert (const char *str)
> +{
> +    Node *tmp = NULL;
> +
> +    assert (str != NULL);
> +
> +    tmp = getnode ();
> +    tmp->type = PASSWDNODE;
> +    gettok (str, ':', &tmp->key);
> +    tmp->data = (char *) str;
> +    tmp->len = strlen (str);
> +    addnode (pass_list, tmp);
> +    tokset = true;
> +}
> diff -Naur ccvs-2006-09-25/src/passwd.h ccvs-2006-09-25.new/src/passwd.h
> --- ccvs-2006-09-25/src/passwd.h      1970-01-01 05:30:00.000000000 +0530
> +++ ccvs-2006-09-25.new/src/passwd.h  2006-10-20 10:46:05.000000000 +0530
> @@ -0,0 +1,33 @@
> +/*
> + * passwd.h: this file is part of the passwd patch for cvs-1.12.13.
> + * Author: PJP <address@hidden>
> + *
> + * Copyright (C) 2006 The Free Software Foundation, Inc.
> + *
> + * Portions Copyright (C) 2006, Prasad J Pandit.
> + *
> + * You may distribute under the terms of the GNU General Public License
> + * as specified in the README file that comes with the CVS source 
> distribution.
> + *
> + * passwd patch for cvs-1.12.13 is ment to add a 'cvs passwd' command to cvs.
> + * This is to facilitate user to change her cvs password from client side 
> using
> + * cvs command line interface.
> + *
> + */
> +
> +#ifndef PASSWD_H
> +#define PASSWD_H
> +
> +#include <stdlib.h>

MDB:
Why is this #include needed? (I am mostly just curious about what is
somehow missing if it is not present.)

> +
> +#define BUFLEN     512
> +#define MAX_LEN    128
> +#define SALTSIZE    12
> +
> +/*
> + * passwd: is the main function for cvs passwd. called by cvs-client, is
> + * supposed to read new password from user and pass it on to the cvs server.
> + */
> +int passwd (int, char *[]);
> +
> +#endif
> diff -Naur ccvs-2006-09-25/src/server.c ccvs-2006-09-25.new/src/server.c
> --- ccvs-2006-09-25/src/server.c      2006-09-15 18:01:56.000000000 +0530
> +++ ccvs-2006-09-25.new/src/server.c  2006-10-20 10:19:50.000000000 +0530
> @@ -35,6 +35,7 @@
>   #include "fileattr.h"
>   #include "gpg.h"
>   #include "ignore.h"
> +#include "passwd.h"
>   #include "repos.h"
>   #include "watch.h"
>   #include "wrapper.h"

MDB:
Another weird hunk above.

> @@ -4898,7 +4899,11 @@
>       do_cvs_command ("version", version);
>   }
> 
> -

MDB:
You may wish to add the above blank line back into the file.

> +static void
> +serve_passwd (char *arg)
> +{
> +    do_cvs_command ("passwd", passwd);
> +}
> 
>   static void
>   serve_init (char *arg)
> @@ -6103,6 +6108,8 @@
>     REQ_LINE("rannotate", serve_rannotate, 0),
>     REQ_LINE("noop", serve_noop, RQ_ROOTLESS),
>     REQ_LINE("version", serve_version, RQ_ROOTLESS),
> +  REQ_LINE("passwd", serve_passwd, 0),
> +  REQ_LINE("passwd-e", serve_noop, RQ_ROOTLESS),
>     REQ_LINE(NULL, NULL, 0)
> 
>   #undef REQ_LINE
> 

MDB:
Another weirdly indented hunk of the patch.

> 
> 
> Thank you!
> -- 
> regards
>     -P J P
> PS: Please don't send me html/attachment/Fwd mails

        -- Mark
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.4 (FreeBSD)

iD8DBQFFOHjtCg7APGsDnFERAhXDAJ4tm7fehqRqmvZWU0MuC4RuK6LdjgCeKM2i
ASNCjAzR/n0rNZtSE0F0qBQ=
=YZXA
-----END PGP SIGNATURE-----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]