$NetBSD: patch-am,v 1.10 2011/12/16 22:32:06 asau Exp $ Add support for "passwd expand gecos". --- ../lib/util/util_pw.c.orig 2011-10-18 22:48:48.000000000 +0400 +++ ../lib/util/util_pw.c 2011-12-16 19:54:39.000000000 +0400 @@ -6,6 +6,7 @@ Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Jeremy Allison 1998-2005 Copyright (C) Andrew Bartlett 2002 + Copyright (C) Luke Mewburn 2004 Copyright (C) Timur Bakeyev 2005 Copyright (C) Bjoern Jacke 2006-2007 @@ -71,10 +72,13 @@ return getgrgid(gid); } +static char *passwd_expand_gecos(const struct passwd *); + struct passwd *tcopy_passwd(TALLOC_CTX *mem_ctx, const struct passwd *from) { struct passwd *ret = talloc_zero(mem_ctx, struct passwd); + char *gecos; if (ret == NULL) return NULL; @@ -83,7 +87,10 @@ ret->pw_passwd = talloc_strdup(ret, from->pw_passwd); ret->pw_uid = from->pw_uid; ret->pw_gid = from->pw_gid; - ret->pw_gecos = talloc_strdup(ret, from->pw_gecos); + gecos = (from->pw_gecos != NULL) ? passwd_expand_gecos(from) : NULL; + ret->pw_gecos = talloc_strdup(ret, gecos); + if (gecos != NULL) + SAFE_FREE(gecos); ret->pw_dir = talloc_strdup(ret, from->pw_dir); ret->pw_shell = talloc_strdup(ret, from->pw_shell); @@ -108,6 +115,41 @@ return tcopy_passwd(mem_ctx, temp); } + +/**************************************************************** + Expand any `&' characters in pw_gecos with a capitalized pw_name. +****************************************************************/ + +static char *passwd_expand_gecos(const struct passwd *pw) +{ + char *p, *bp, *buf; + size_t ac, buflen; + + if (!lp_passwd_expand_gecos()) { + return smb_xstrdup(pw->pw_gecos); + } + + ac = 0; + /* count number of `&' in pw_gecos */ + for (p = pw->pw_gecos; *p; p++) { + if (*p == '&') + ac++; + } + buflen = strlen(pw->pw_gecos) + (ac * (strlen(pw->pw_name) - 1)) + 1; + buf = smb_xmalloc_array(sizeof(char), buflen); + bp = buf; + for (p = pw->pw_gecos; *p; p++) { + if (*p == '&') { /* replace & with capitalized pw_name */ + ac = snprintf(bp, buflen - (bp - buf), + "%s", pw->pw_name); + *bp = toupper((unsigned char)*bp); + bp += ac; + } else + *bp++ = *p; + } + return buf; +} + /**************************************************************************** talloc'ed version of getpwuid. ****************************************************************************/