$NetBSD: patch-bv,v 1.2 2007/02/11 18:39:04 tron Exp $ --- lib/util_pw.c.orig 2006-04-20 03:29:23.000000000 +0100 +++ lib/util_pw.c 2007-02-11 17:57:22.000000000 +0000 @@ -4,6 +4,7 @@ Safe versions of getpw* calls Copyright (C) Andrew Bartlett 2002 + Copyright (C) Luke Mewburn 2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,6 +26,7 @@ struct passwd *tcopy_passwd(TALLOC_CTX *mem_ctx, const struct passwd *from) { struct passwd *ret = TALLOC_P(mem_ctx, struct passwd); + char *gecos; if (!ret) { return NULL; } @@ -32,7 +34,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); return ret; @@ -126,3 +131,38 @@ return tcopy_passwd(mem_ctx, temp); } + + +/**************************************************************** + Expand any `&' characters in pw_gecos with a capitalized pw_name. +****************************************************************/ + +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; +}