$NetBSD: patch-am,v 1.1.1.1 2010/02/16 16:24:16 taca Exp $ Add support for "passwd expand gecos". --- lib/util_pw.c.orig 2010-01-14 10:12:10.000000000 +0000 +++ lib/util_pw.c @@ -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 @@ -21,9 +22,12 @@ #include "includes.h" +static char *passwd_expand_gecos(const struct passwd *); + 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; } @@ -31,7 +35,10 @@ struct passwd *tcopy_passwd(TALLOC_CTX * 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; @@ -85,3 +92,38 @@ struct passwd *getpwuid_alloc(TALLOC_CTX 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; +}