aboutsummaryrefslogtreecommitdiff
path: root/pwd/putpwent.c
diff options
context:
space:
mode:
Diffstat (limited to 'pwd/putpwent.c')
-rw-r--r--pwd/putpwent.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/pwd/putpwent.c b/pwd/putpwent.c
index 8be58c2..16b9c6f 100644
--- a/pwd/putpwent.c
+++ b/pwd/putpwent.c
@@ -18,37 +18,47 @@
#include <errno.h>
#include <stdio.h>
#include <pwd.h>
+#include <nss.h>
#define _S(x) x ?: ""
-/* Write an entry to the given stream.
- This must know the format of the password file. */
+/* Write an entry to the given stream. This must know the format of
+ the password file. If the input contains invalid characters,
+ return EINVAL, or replace them with spaces (if they are contained
+ in the GECOS field). */
int
-putpwent (p, stream)
- const struct passwd *p;
- FILE *stream;
+putpwent (const struct passwd *p, FILE *stream)
{
- if (p == NULL || stream == NULL)
+ if (p == NULL || stream == NULL
+ || p->pw_name == NULL || !__nss_valid_field (p->pw_name)
+ || !__nss_valid_field (p->pw_passwd)
+ || !__nss_valid_field (p->pw_dir)
+ || !__nss_valid_field (p->pw_shell))
{
__set_errno (EINVAL);
return -1;
}
+ int ret;
+ char *gecos_alloc;
+ const char *gecos = __nss_rewrite_field (p->pw_gecos, &gecos_alloc);
+
+ if (gecos == NULL)
+ return -1;
+
if (p->pw_name[0] == '+' || p->pw_name[0] == '-')
- {
- if (fprintf (stream, "%s:%s:::%s:%s:%s\n",
- p->pw_name, _S (p->pw_passwd),
- _S (p->pw_gecos), _S (p->pw_dir), _S (p->pw_shell)) < 0)
- return -1;
- }
+ ret = fprintf (stream, "%s:%s:::%s:%s:%s\n",
+ p->pw_name, _S (p->pw_passwd),
+ gecos, _S (p->pw_dir), _S (p->pw_shell));
else
- {
- if (fprintf (stream, "%s:%s:%lu:%lu:%s:%s:%s\n",
- p->pw_name, _S (p->pw_passwd),
- (unsigned long int) p->pw_uid,
- (unsigned long int) p->pw_gid,
- _S (p->pw_gecos), _S (p->pw_dir), _S (p->pw_shell)) < 0)
- return -1;
- }
- return 0;
+ ret = fprintf (stream, "%s:%s:%lu:%lu:%s:%s:%s\n",
+ p->pw_name, _S (p->pw_passwd),
+ (unsigned long int) p->pw_uid,
+ (unsigned long int) p->pw_gid,
+ gecos, _S (p->pw_dir), _S (p->pw_shell));
+
+ free (gecos_alloc);
+ if (ret >= 0)
+ ret = 0;
+ return ret;
}