The default password in a new container is now auto-generated using
phoneme rules and (good) random numbers.

Even if the default random password is set in a distribution-specific
template and you use the download template to pull a pre-built rootfs
image, you will get the same password every time unless the pre-built
rootfs image is updated.

So, the default random password in a new container is to be set after
container creation.  The user names whose passwords to be changed are
stored in *.chpasswd file which is located at /usr/share/lxc/config.
Each line of the file specifies a user name whose password is to be
changed.  If the target *.chpasswd file does not exist, no password is
changed in a new container.

Signed-off-by: TAMUKI Shoichi <tam...@linet.gr.jp>
---
 config/templates/Makefile.am           |  27 +++-
 config/templates/altlinux.chpasswd     |   1 +
 config/templates/archlinux.chpasswd    |   1 +
 config/templates/busybox.chpasswd      |   1 +
 config/templates/centos.chpasswd       |   1 +
 config/templates/debian.chpasswd       |   1 +
 config/templates/fedora.chpasswd       |   1 +
 config/templates/gentoo.chpasswd       |   1 +
 config/templates/openmandriva.chpasswd |   1 +
 config/templates/opensuse.chpasswd     |   1 +
 config/templates/oracle.chpasswd       |   2 +
 config/templates/plamo.chpasswd        |   1 +
 config/templates/ubuntu.chpasswd       |   1 +
 src/lxc/Makefile.am                    |   2 +
 src/lxc/lxccontainer.c                 | 218 ++++++++++++++++++++++++++++++++-
 src/lxc/pwgen.c                        | 201 ++++++++++++++++++++++++++++++
 src/lxc/pwgen.h                        |  26 ++++
 17 files changed, 483 insertions(+), 4 deletions(-)
 create mode 100644 config/templates/altlinux.chpasswd
 create mode 100644 config/templates/archlinux.chpasswd
 create mode 100644 config/templates/busybox.chpasswd
 create mode 100644 config/templates/centos.chpasswd
 create mode 100644 config/templates/debian.chpasswd
 create mode 100644 config/templates/fedora.chpasswd
 create mode 100644 config/templates/gentoo.chpasswd
 create mode 100644 config/templates/openmandriva.chpasswd
 create mode 100644 config/templates/opensuse.chpasswd
 create mode 100644 config/templates/oracle.chpasswd
 create mode 100644 config/templates/plamo.chpasswd
 create mode 100644 config/templates/ubuntu.chpasswd
 create mode 100644 src/lxc/pwgen.c
 create mode 100644 src/lxc/pwgen.h

diff --git a/config/templates/Makefile.am b/config/templates/Makefile.am
index 82ca8be..22b231f 100644
--- a/config/templates/Makefile.am
+++ b/config/templates/Makefile.am
@@ -1,30 +1,55 @@
 templatesconfigdir=@LXCTEMPLATECONFIG@
 
-EXTRA_DIST = common.seccomp
+EXTRA_DIST = \
+       altlinux.chpasswd \
+       archlinux.chpasswd \
+       busybox.chpasswd \
+       centos.chpasswd \
+       common.seccomp \
+       debian.chpasswd \
+       fedora.chpasswd \
+       gentoo.chpasswd \
+       openmandriva.chpasswd \
+       opensuse.chpasswd \
+       oracle.chpasswd \
+       plamo.chpasswd \
+       ubuntu.chpasswd
 
 templatesconfig_DATA = \
+       altlinux.chpasswd \
+       archlinux.chpasswd \
        archlinux.common.conf \
        archlinux.userns.conf \
+       busybox.chpasswd \
+       centos.chpasswd \
        centos.common.conf \
        centos.userns.conf \
        common.conf \
        common.seccomp \
+       debian.chpasswd \
        debian.common.conf \
        debian.userns.conf \
+       fedora.chpasswd \
        fedora.common.conf \
        fedora.userns.conf \
+       gentoo.chpasswd \
        gentoo.common.conf \
        gentoo.moresecure.conf \
        gentoo.userns.conf \
+       openmandriva.chpasswd \
+       opensuse.chpasswd \
        opensuse.common.conf \
        opensuse.userns.conf \
+       oracle.chpasswd \
        oracle.common.conf \
        oracle.userns.conf \
+       plamo.chpasswd \
        plamo.common.conf \
        plamo.userns.conf \
        ubuntu-cloud.common.conf \
        ubuntu-cloud.lucid.conf \
        ubuntu-cloud.userns.conf \
+       ubuntu.chpasswd
        ubuntu.common.conf \
        ubuntu.lucid.conf \
        ubuntu.userns.conf \
diff --git a/config/templates/altlinux.chpasswd 
b/config/templates/altlinux.chpasswd
new file mode 100644
index 0000000..d8649da
--- /dev/null
+++ b/config/templates/altlinux.chpasswd
@@ -0,0 +1 @@
+root
diff --git a/config/templates/archlinux.chpasswd 
b/config/templates/archlinux.chpasswd
new file mode 100644
index 0000000..d8649da
--- /dev/null
+++ b/config/templates/archlinux.chpasswd
@@ -0,0 +1 @@
+root
diff --git a/config/templates/busybox.chpasswd 
b/config/templates/busybox.chpasswd
new file mode 100644
index 0000000..d8649da
--- /dev/null
+++ b/config/templates/busybox.chpasswd
@@ -0,0 +1 @@
+root
diff --git a/config/templates/centos.chpasswd b/config/templates/centos.chpasswd
new file mode 100644
index 0000000..d8649da
--- /dev/null
+++ b/config/templates/centos.chpasswd
@@ -0,0 +1 @@
+root
diff --git a/config/templates/debian.chpasswd b/config/templates/debian.chpasswd
new file mode 100644
index 0000000..d8649da
--- /dev/null
+++ b/config/templates/debian.chpasswd
@@ -0,0 +1 @@
+root
diff --git a/config/templates/fedora.chpasswd b/config/templates/fedora.chpasswd
new file mode 100644
index 0000000..d8649da
--- /dev/null
+++ b/config/templates/fedora.chpasswd
@@ -0,0 +1 @@
+root
diff --git a/config/templates/gentoo.chpasswd b/config/templates/gentoo.chpasswd
new file mode 100644
index 0000000..d8649da
--- /dev/null
+++ b/config/templates/gentoo.chpasswd
@@ -0,0 +1 @@
+root
diff --git a/config/templates/openmandriva.chpasswd 
b/config/templates/openmandriva.chpasswd
new file mode 100644
index 0000000..d8649da
--- /dev/null
+++ b/config/templates/openmandriva.chpasswd
@@ -0,0 +1 @@
+root
diff --git a/config/templates/opensuse.chpasswd 
b/config/templates/opensuse.chpasswd
new file mode 100644
index 0000000..d8649da
--- /dev/null
+++ b/config/templates/opensuse.chpasswd
@@ -0,0 +1 @@
+root
diff --git a/config/templates/oracle.chpasswd b/config/templates/oracle.chpasswd
new file mode 100644
index 0000000..e4b3edb
--- /dev/null
+++ b/config/templates/oracle.chpasswd
@@ -0,0 +1,2 @@
+root
+oracle
diff --git a/config/templates/plamo.chpasswd b/config/templates/plamo.chpasswd
new file mode 100644
index 0000000..d8649da
--- /dev/null
+++ b/config/templates/plamo.chpasswd
@@ -0,0 +1 @@
+root
diff --git a/config/templates/ubuntu.chpasswd b/config/templates/ubuntu.chpasswd
new file mode 100644
index 0000000..e9e5f7c
--- /dev/null
+++ b/config/templates/ubuntu.chpasswd
@@ -0,0 +1 @@
+ubuntu
diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
index da3f78e..fe6793f 100644
--- a/src/lxc/Makefile.am
+++ b/src/lxc/Makefile.am
@@ -89,6 +89,7 @@ liblxc_so_SOURCES = \
        lxcutmp.c lxcutmp.h \
        lxclock.h lxclock.c \
        lxccontainer.c lxccontainer.h \
+       pwgen.c pwgen.h \
        version.h \
        \
        $(LSM_SOURCES)
@@ -117,6 +118,7 @@ AM_CFLAGS=-I$(top_srcdir)/src \
        -DLXCINITDIR=\"$(LXCINITDIR)\" \
        -DLIBEXECDIR=\"$(LIBEXECDIR)\" \
        -DLXCTEMPLATEDIR=\"$(LXCTEMPLATEDIR)\" \
+       -DLXCTEMPLATECONFIG=\"$(LXCTEMPLATECONFIG)\" \
        -DLOGPATH=\"$(LOGPATH)\" \
        -DLXC_DEFAULT_CONFIG=\"$(LXC_DEFAULT_CONFIG)\" \
        -DLXC_USERNIC_DB=\"$(LXC_USERNIC_DB)\" \
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index dbbd24a..2301355 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -56,6 +56,7 @@
 #include "namespace.h"
 #include "lxclock.h"
 #include "sync.h"
+#include "pwgen.h"
 
 #if HAVE_IFADDRS_H
 #include <ifaddrs.h>
@@ -868,6 +869,50 @@ static char *get_template_path(const char *t)
        return tpath;
 }
 
+/*
+ * Given the '-t' template option to lxc-create, figure out what to
+ * do.  If the template is a full executable path, just return NULL.
+ * If the template is 'download', use the effective template instead.
+ * If it is something like 'ubuntu', then return LXCTEMPLATECONFIG/
+ * ubuntu.chpasswd.  Return the chpasswd file, or return NULL if not
+ * exist.
+ */
+static char *get_chpasswd_path(const char *t, char *const argv[])
+{
+       int i, ret, len;
+       const char *et = t;
+       char *p, *chpwpath;
+
+       if (t[0] == '/')
+               return NULL;
+       if (!strcmp(t, "download")) {
+               for (i = 0, et = NULL; argv[i] && !et; i++)
+                       if (!strcmp(argv[i], "-d"))
+                               et = argv[i + 1];
+                       else if (!strncmp(argv[i], "--d", 3))
+                               et = ((p = strchr(argv[i], '=')) != NULL)
+                                               ? p + 1 : argv[i + 1];
+       } else
+               et = t;
+
+       len = strlen(LXCTEMPLATECONFIG) + strlen(et) + strlen(".chpasswd") + 2;
+       chpwpath = malloc(len);
+       if (!chpwpath)
+               return NULL;
+       ret = snprintf(chpwpath, len, "%s/%s.chpasswd", LXCTEMPLATECONFIG, et);
+       if (ret < 0 || ret >= len) {
+               free(chpwpath);
+               return NULL;
+       }
+       if (access(chpwpath, R_OK) < 0) {
+               NOTICE("nothing to do chpasswd: %s", et);
+               free(chpwpath);
+               return NULL;
+       }
+
+       return chpwpath;
+}
+
 static char *lxcbasename(char *path)
 {
        char *p = path + strlen(path) - 1;
@@ -880,8 +925,9 @@ static char *figureout_rootfs(struct lxc_conf *conf);
 static char **prepend_lxc_usernsexec(char **tpath, struct lxc_conf *conf,
                int nargs, char **newargv);
 
-static bool create_run_template(struct lxc_container *c, char *tpath, bool 
quiet,
-                               char *const argv[])
+static bool create_run_template(struct lxc_container *c, char *tpath,
+               char **const uname, char **const passwd, bool quiet,
+               char *const argv[])
 {
        pid_t pid;
 
@@ -979,6 +1025,99 @@ static bool create_run_template(struct lxc_container *c, 
char *tpath, bool quiet
                return false;
        }
 
+       if (!uname)
+               return true;
+
+       pid = fork();
+       if (pid < 0) {
+               SYSERROR("failed to fork task for chpasswd");
+               return false;
+       }
+
+       if (pid == 0) { // child
+               char *sharg, *rootfs;
+               char *chpasswd = NULL;
+               int i, j;
+               int ret, len, nargs = 0;
+               char *p;
+               char **newargv;
+               struct lxc_conf *conf = c->lxc_conf;
+
+               if (quiet) {
+                       close(0);
+                       close(1);
+                       close(2);
+                       open("/dev/zero", O_RDONLY);
+                       open("/dev/null", O_RDWR);
+                       open("/dev/null", O_RDWR);
+               }
+
+               rootfs=figureout_rootfs(conf);
+
+               /*
+                * create our new array, pre-pend the template name and
+                * base args
+                */
+               nargs += 3; // "sh", "-c" and
+               // "echo \"$chpasswd\" | chroot $rootfs /usr/sbin/chpasswd"
+               // args
+
+               newargv = malloc(nargs * sizeof(*newargv));
+               if (!newargv)
+                       exit(1);
+               newargv[0] = "sh";
+               newargv[1] = "-c";
+
+               for (i = j = 0; uname[i]; i++, j += len - 1) {
+                       len = strlen(uname[i]) + strlen(passwd[i]) + 3;
+                       chpasswd = realloc(chpasswd, j + len);
+                       if (!chpasswd)
+                               exit(1);
+                       ret = snprintf(chpasswd + j, len, "%s:%s\n",
+                                       uname[i], passwd[i]);
+                       if (ret < 0 || ret >= len)
+                               exit(1);
+               }
+               if ((p = strrchr(chpasswd, '\n')) != NULL)
+                       *p = '\0';
+
+               len = strlen("echo") + strlen(chpasswd)
+                               + strlen("chroot") + strlen(rootfs)
+                               + strlen("/usr/sbin/chpasswd") + 9;
+               sharg = malloc(len);
+               if (!sharg)
+                       exit(1);
+               ret = snprintf(sharg, len,
+                               "echo \"%s\" | chroot %s /usr/sbin/chpasswd",
+                               chpasswd, rootfs);
+               if (ret < 0 || ret >= len)
+                       exit(1);
+               newargv[2] = sharg;
+
+               /* add trailing NULL */
+               nargs++;
+               newargv = realloc(newargv, nargs * sizeof(*newargv));
+               if (!newargv)
+                       exit(1);
+               newargv[nargs - 1] = NULL;
+
+               tpath = "sh";
+               /* prepend the template command with lxc-usernsexec */
+               if (!lxc_list_empty(&conf->id_map))
+                       newargv = prepend_lxc_usernsexec(&tpath, conf,
+                                       nargs, newargv);
+
+               /* execute */
+               execvp(tpath, newargv);
+               SYSERROR("failed to execute chpasswd");
+               exit(1);
+       }
+
+       if (wait_for_pid(pid) != 0) {
+               ERROR("chpasswd for %s failed", c->name);
+               return false;
+       }
+
        return true;
 }
 
@@ -1275,6 +1414,12 @@ static bool lxcapi_create(struct lxc_container *c, const 
char *t,
        bool ret = false;
        pid_t pid;
        char *tpath = NULL;
+       char *chpwpath = NULL;
+       char **uname = NULL, **passwd = NULL;
+       int i;
+       FILE *fp;
+       char *p, *line = NULL;
+       size_t len = 0;
        int partial_fd;
 
        if (!c)
@@ -1286,6 +1431,49 @@ static bool lxcapi_create(struct lxc_container *c, const 
char *t,
                        ERROR("bad template: %s", t);
                        goto out;
                }
+               chpwpath = get_chpasswd_path(t, argv);
+               if (chpwpath) {
+                       fp = fopen(chpwpath, "r");
+                       for (i = 0; getline(&line, &len, fp) != -1; i++) {
+                               if ((p = strchr(line, '\n')) != NULL)
+                                       *p = '\0';
+                               if (!(uname = realloc(uname,
+                                               (i + 1) * sizeof(*uname)))) {
+                                       SYSERROR("out of memory");
+                                       exit(1);
+                               }
+                               if (!(uname[i] = malloc(strlen(line) + 1))) {
+                                       SYSERROR("out of memory");
+                                       exit(1);
+                               }
+                               strcpy(uname[i], line);
+                               if (!(passwd = realloc(passwd,
+                                               (i + 1) * sizeof(*passwd)))) {
+                                       SYSERROR("out of memory");
+                                       exit(1);
+                               }
+                               if (!(passwd[i] = malloc(11))) {
+                                       SYSERROR("out of memory");
+                                       exit(1);
+                               }
+                               pw_phonemes(passwd[i], 10);
+                       }
+                       if (line)
+                               free(line);
+                       fclose(fp);
+                       if (!(uname = realloc(uname,
+                                       (i + 1) * sizeof(*uname)))) {
+                               SYSERROR("out of memory");
+                               exit(1);
+                       }
+                       uname[i] = NULL;
+                       if (!(passwd = realloc(passwd,
+                                       (i + 1) * sizeof(*passwd)))) {
+                               SYSERROR("out of memory");
+                               exit(1);
+                       }
+                       passwd[i] = NULL;
+               }
        }
 
        /*
@@ -1375,9 +1563,17 @@ static bool lxcapi_create(struct lxc_container *c, const 
char *t,
        if (!load_config_locked(c, c->configfile))
                goto out_unlock;
 
-       if (!create_run_template(c, tpath, !!(flags & LXC_CREATE_QUIET), argv))
+       if (!create_run_template(c, tpath, uname, passwd,
+                       !!(flags & LXC_CREATE_QUIET), argv))
                goto out_unlock;
 
+       if (uname)
+               for (i = 0; uname[i]; i++)
+                       printf("The default %s password is: %s\n",
+                                       uname[i], passwd[i]);
+       else
+               printf("No password is changed.\n");
+
        // now clear out the lxc_conf we have, reload from the created
        // container
        lxcapi_clear_config(c);
@@ -1399,6 +1595,22 @@ out:
 free_tpath:
        if (tpath)
                free(tpath);
+       if (chpwpath)
+               free(chpwpath);
+       if (uname) {
+               char **pp;
+
+               for (pp = uname; *pp; pp++)
+                       free(*pp);
+               free(uname);
+       }
+       if (passwd) {
+               char **pp;
+
+               for (pp = passwd; *pp; pp++)
+                       free(*pp);
+               free(passwd);
+       }
        return ret;
 }
 
diff --git a/src/lxc/pwgen.c b/src/lxc/pwgen.c
new file mode 100644
index 0000000..c5a83d0
--- /dev/null
+++ b/src/lxc/pwgen.c
@@ -0,0 +1,201 @@
+/*
+ * pwgen.c --- generate secure password using phoneme rules and
+ *             (good) random numbers.
+ *
+ * Copyright (C) 2001,2002 by Theodore Ts'o
+ * Copyright (C) 2014 by TAMUKI Shoichi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "pwgen.h"
+
+struct pw_element {
+       const char *str;
+       int flags;
+};
+
+/* Flags for the pw_element */
+#define CONSONANT      0x0001
+#define VOWEL          0x0002
+#define DIPTHONG       0x0004
+#define NOT_FIRST      0x0008
+
+struct pw_element elements[] = {
+       { "a",  VOWEL },
+       { "ae", VOWEL | DIPTHONG },
+       { "ah", VOWEL | DIPTHONG },
+       { "ai", VOWEL | DIPTHONG },
+       { "b",  CONSONANT },
+       { "c",  CONSONANT },
+       { "ch", CONSONANT | DIPTHONG },
+       { "d",  CONSONANT },
+       { "e",  VOWEL },
+       { "ee", VOWEL | DIPTHONG },
+       { "ei", VOWEL | DIPTHONG },
+       { "f",  CONSONANT },
+       { "g",  CONSONANT },
+       { "gh", CONSONANT | DIPTHONG | NOT_FIRST },
+       { "h",  CONSONANT },
+       { "i",  VOWEL },
+       { "ie", VOWEL | DIPTHONG },
+       { "j",  CONSONANT },
+       { "k",  CONSONANT },
+       { "l",  CONSONANT },
+       { "m",  CONSONANT },
+       { "n",  CONSONANT },
+       { "ng", CONSONANT | DIPTHONG | NOT_FIRST },
+       { "o",  VOWEL },
+       { "oh", VOWEL | DIPTHONG },
+       { "oo", VOWEL | DIPTHONG },
+       { "p",  CONSONANT },
+       { "ph", CONSONANT | DIPTHONG },
+       { "qu", CONSONANT | DIPTHONG },
+       { "r",  CONSONANT },
+       { "s",  CONSONANT },
+       { "sh", CONSONANT | DIPTHONG },
+       { "t",  CONSONANT },
+       { "th", CONSONANT | DIPTHONG },
+       { "u",  VOWEL },
+       { "v",  CONSONANT },
+       { "w",  CONSONANT },
+       { "x",  CONSONANT },
+       { "y",  CONSONANT },
+       { "z",  CONSONANT }
+};
+
+#define NUM_ELEMENTS (sizeof(elements) / sizeof(struct pw_element))
+
+/* Flags for the pwgen function */
+#define PW_DIGITS      0x0001  /* At least one digit */
+#define PW_UPPERS      0x0002  /* At least one upper letter */
+
+static int pw_number(int max_num);
+static int get_random_fd(void);
+
+void pw_phonemes(char *buf, int size)
+{
+       int feature_flags, should_be, prev, first;
+       int c, i, len, flags;
+       const char *str;
+
+try_again:
+       feature_flags = PW_DIGITS | PW_UPPERS;
+       should_be = (pw_number(2)) ? VOWEL : CONSONANT;
+       prev = 0, first = 1;
+       c = 0;
+       while (c < size) {
+               str = elements[i = pw_number(NUM_ELEMENTS)].str;
+               len = strlen(str);
+               flags = elements[i].flags;
+               /* Don't allow us to overflow the buffer */
+               if (c + len > size)
+                       continue;
+               /* Filter on the basic type of the next element */
+               if (!(flags & should_be))
+                       continue;
+               /* Handle the NOT_FIRST flag */
+               if (first && flags & NOT_FIRST)
+                       continue;
+               /* Don't allow VOWEL followed a Vowel/Dipthong pair */
+               if (prev & VOWEL && flags & VOWEL && flags & DIPTHONG)
+                       continue;
+               /*
+                * OK, we found an element which matches our criteria,
+                * let's do it!
+                */
+               strcpy(buf + c, str);
+               if ((first || flags & CONSONANT) && !pw_number(5)) {
+                       buf[c] = toupper(buf[c]);
+                       feature_flags &= ~PW_UPPERS;
+               }
+               /* Time to stop? */
+               if ((c += len) == size)
+                       break;
+               if (!first && pw_number(10) < 3) {
+                       buf[c++] = '0' + pw_number(10), buf[c] = 0;
+                       feature_flags &= ~PW_DIGITS;
+                       should_be = (pw_number(2)) ? VOWEL : CONSONANT;
+                       prev = 0, first = 1;
+                       continue;
+               }
+               /* OK, figure out what the next element should be */
+               should_be = (should_be == CONSONANT) ? VOWEL
+                               : ((prev & VOWEL || flags & DIPTHONG
+                               || pw_number(5) < 2) ? VOWEL : CONSONANT);
+               prev = flags, first = 0;
+       }
+       if (feature_flags & (PW_DIGITS | PW_UPPERS))
+               goto try_again;
+}
+
+/*
+ * Generate a random number n, where 0 <= n < max_num, using
+ * /dev/urandom if possible.
+ */
+static int pw_number(int max_num)
+{
+       int fd, i;
+       unsigned int rand_num;
+       char *cp = (char *) &rand_num;
+       int nbytes = 4, lose_counter = 0;
+
+       if ((fd = get_random_fd()) >= 0)
+               while (nbytes > 0)
+                       if ((i = read(fd, cp, nbytes)) < 0
+                                       && (errno == EINTR || errno == EAGAIN))
+                               continue;
+                       else if (i <= 0) {
+                               if (lose_counter++ == 8)
+                                       break;
+                       } else
+                               cp += i, nbytes -= i, lose_counter = 0;
+       close(fd);
+       if (nbytes == 0)
+               return rand_num % max_num;
+       /* OK, we weren't able to use /dev/random, fall back to rand/rand48 */
+       return (int) (drand48() * max_num);
+}
+
+/* Borrowed/adapted from e2fsprogs's UUID generation code */
+static int get_random_fd(void)
+{
+       static int fd = -2;
+       struct timeval tv;
+       int i;
+
+       if (fd == -2) {
+               gettimeofday(&tv, 0);
+               if ((fd = open("/dev/urandom", O_RDONLY)) == -1)
+                       fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
+               srand48(tv.tv_sec << 9 ^ tv.tv_usec >> 11 ^ getpid()
+                               ^ getpgrp() << 15);
+       }
+       /* Crank the random number generator a few times */
+       gettimeofday(&tv, 0);
+       for (i = 0; i < ((tv.tv_sec ^ tv.tv_usec) & 0x1f); i++)
+               drand48();
+       return fd;
+}
+
diff --git a/src/lxc/pwgen.h b/src/lxc/pwgen.h
new file mode 100644
index 0000000..9d0adc5
--- /dev/null
+++ b/src/lxc/pwgen.h
@@ -0,0 +1,26 @@
+/*
+ * pwgen.h --- header file for password generator
+ *
+ * Copyright (C) 2001,2002 by Theodore Ts'o
+ * Copyright (C) 2014 by TAMUKI Shoichi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PWGEN_H
+#define __PWGEN_H
+extern void pw_phonemes(char *buf, int size);
+#endif
+
-- 
1.9.0
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to