jailsetup.sh: create a symlink in chroot if necessary for alternates
[girocco.git] / src / get_user_uuid.c
blobdd27494bf0b66bb331aab0a21f9d888bbcd6997f
1 /*
3 get_user_uuid.c -- get user UUID from passwd file
4 Copyright (c) 2014 Kyle J. McKay. All rights reserved.
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 USAGE: get_user_uuid username
24 Exit code 0 for yes, non-zero for no
25 If username has a UUID returns yes and echos it to stdout
26 Wrong number of or bad arguments exits with non-zero
27 Directly reads compiled in PASSWD_FILE location
30 #ifndef PASSWD_FILE
31 #error PASSWD_FILE must be defined to a string which is the full pathname to\
32 the /etc/passwd format file to read
33 #endif
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdio.h>
39 #define BADCHARS ":,# \t\r\n"
40 #define MAX_LINE_SIZE 16384 /* includes trailing \n and \0 */
41 #define MAX_NAME_LEN 64
43 static char linebuffer[MAX_LINE_SIZE];
45 int is_valid_name(const char *name)
47 size_t len;
49 if (!name || !*name)
50 return 0;
51 len = strlen(name);
52 if (len > MAX_NAME_LEN || strcspn(name, BADCHARS) != len)
53 return 0;
54 return 1;
57 int main(int argc, char *argv[])
59 FILE *passwdfile;
60 size_t len;
62 if (argc != 2)
63 return EXIT_FAILURE;
64 if (!is_valid_name(argv[1]))
65 return EXIT_FAILURE;
67 len = strlen(argv[2]);
69 passwdfile = fopen(PASSWD_FILE, "r");
70 if (!passwdfile)
71 return EXIT_FAILURE;
72 while (fgets(linebuffer, sizeof(linebuffer)-1, passwdfile)) {
73 char *trimmed, *uuid;
74 size_t len = strlen(linebuffer);
76 if (len >= sizeof(linebuffer) - 2)
77 return EXIT_FAILURE;
78 if (len && linebuffer[len-1] == '\n')
79 linebuffer[--len] = '\0';
80 trimmed = linebuffer + strspn(linebuffer, " \t");
81 if (!*trimmed || *trimmed == '#')
82 continue;
83 if (trimmed != linebuffer)
84 return EXIT_FAILURE;
85 trimmed = strchr(linebuffer, ':');
86 if (!trimmed)
87 return EXIT_FAILURE;
88 *trimmed = '\0';
89 if (strcmp(linebuffer, argv[1]))
90 continue; /* not the user we're looking for */
91 trimmed = strchr(trimmed + 1, ':');
92 if (!trimmed)
93 return EXIT_FAILURE;
94 trimmed = strchr(trimmed + 1, ':');
95 if (!trimmed)
96 return EXIT_FAILURE;
97 trimmed = strchr(trimmed + 1, ':');
98 if (!trimmed)
99 return EXIT_FAILURE;
100 uuid = trimmed;
101 trimmed = strchr(trimmed + 1, ':');
102 if (trimmed)
103 *trimmed = '\0';
104 uuid = strchr(uuid + 1, ',');
105 if (!uuid)
106 return EXIT_FAILURE;
107 trimmed = strchr(++uuid, ',');
108 if (trimmed)
109 *trimmed = '\0';
110 if (*uuid)
111 printf("%s\n", uuid);
112 return *uuid ? EXIT_SUCCESS : EXIT_FAILURE;
114 return EXIT_FAILURE;