[go: up one dir, main page]

File: uid_gid_lookup.c

package info (click to toggle)
acl 2.3.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,200 kB
  • sloc: ansic: 5,916; sh: 5,379; perl: 279; makefile: 49; sed: 16
file content (128 lines) | stat: -rw-r--r-- 2,552 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
  File: uid_gid_lookup.c

  Copyright (C) 2023 Andreas Gruenbacher <andreas.gruenbacher@gmail.com>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, see <https://www.gnu.org/licenses/>.
*/


#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#include "libacl.h"
#include "misc.h"

int
get_id(const char *token, id_t *id_p)
{
	char *ep;
	long l;
	l = strtol(token, &ep, 0);
	if (*ep != '\0')
		return -1;
	if (l < 0) {
		/*
		  Negative values are interpreted as 16-bit numbers
		  so that id -2 maps to 65534 (nobody/nogroup), etc.
		*/
		l &= 0xFFFF;
	}
	*id_p = l;
	return 0;
}

static char *
grow_buffer(char **buffer, size_t *bufsize, int type)
{
	long size = *bufsize;
	char *buf;

	if (!size) {
		size = sysconf(type);
		if (size <= 0)
			size = 16384;
	} else {
		size *= 2;
	}

	buf = realloc(*buffer, size);
	if (buf) {
		*buffer = buf;
		*bufsize = size;
	}
	return buf;
}

int
get_uid(const char *token, uid_t *uid_p)
{
	struct passwd passwd, *result = NULL;
	char *buffer = NULL;
	size_t bufsize = 0;
	int err;
	if (get_id(token, uid_p) == 0)
		return 0;

	for(;;) {
		if(!grow_buffer(&buffer, &bufsize, _SC_GETPW_R_SIZE_MAX))
			break;

		err = getpwnam_r(token, &passwd, buffer, bufsize, &result);
		if (result) {
			*uid_p = passwd.pw_uid;
			break;
		}
		if (err == ERANGE)
			continue;
		errno = err ? err : EINVAL;
		break;
	}
	free(buffer);
	return result ? 0 : -1;
}


int
get_gid(const char *token, gid_t *gid_p)
{
	struct group group, *result = NULL;
	char *buffer = NULL;
	size_t bufsize = 0;
	int err;
	if (get_id(token, (uid_t *)gid_p) == 0)
		return 0;

	for(;;) {
		if(!grow_buffer(&buffer, &bufsize, _SC_GETGR_R_SIZE_MAX))
			break;

		err = getgrnam_r(token, &group, buffer, bufsize, &result);
		if (result) {
			*gid_p = group.gr_gid;
			break;
		}
		if (err == ERANGE)
			continue;
		errno = err ? err : EINVAL;
		break;
	}

	free(buffer);
	return result ? 0 : -1;
}