[lxc-devel] [PATCH 3/3] Improve setting the default password in a new container
TAMUKI Shoichi
tamuki at linet.gr.jp
Mon Oct 6 10:31:49 UTC 2014
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 <tamuki at 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
More information about the lxc-devel
mailing list