#define MAX_LABEL_LENGTH 1024
+#if !defined(NO_DEFAULT_PEERCRED) && !defined(ADD_DEFAULT_PEERCRED)
+# define NO_DEFAULT_PEERCRED
+#endif
+
+#if !defined(DEFAULT_PEERSEC_LABEL)
+# define DEFAULT_PEERSEC_LABEL "NoLabel"
+#endif
+#if !defined(DEFAULT_PEERCRED_UID)
+# define DEFAULT_PEERCRED_UID 99 /* nobody */
+#endif
+#if !defined(DEFAULT_PEERCRED_GID)
+# define DEFAULT_PEERCRED_GID 99 /* nobody */
+#endif
+#if !defined(DEFAULT_PEERCRED_PID)
+# define DEFAULT_PEERCRED_PID 0 /* no process */
+#endif
+
static struct afb_cred *current;
static struct afb_cred *mkcred(uid_t uid, gid_t gid, pid_t pid, const char *label, size_t size)
{
struct afb_cred *cred;
- char *dest;
-
- cred = malloc(1 + size + sizeof *cred);
+ char *dest, user[64];
+ size_t i;
+ uid_t u;
+
+ i = 0;
+ u = uid;
+ do {
+ user[i++] = (char)('0' + u % 10);
+ u = u / 10;
+ } while(u && i < sizeof user);
+
+ cred = malloc(2 + i + size + sizeof *cred);
if (!cred)
errno = ENOMEM;
else {
cred->gid = gid;
cred->pid = pid;
dest = (char*)(&cred[1]);
- memcpy(dest, label, size);
- dest[size] = 0;
+ cred->user = dest;
+ while(i)
+ *dest++ = user[--i];
+ *dest++ = 0;
cred->label = dest;
cred->id = dest;
+ memcpy(dest, label, size);
+ dest[size] = 0;
dest = strrchr(dest, ':');
- if (dest && dest[1])
+ if (dest)
cred->id = &dest[1];
}
return cred;
struct afb_cred *afb_cred_create(uid_t uid, gid_t gid, pid_t pid, const char *label)
{
- label = label ? : "";
+ label = label ? : DEFAULT_PEERSEC_LABEL;
return mkcred(uid, gid, pid, label, strlen(label));
}
/* get the credentials */
length = (socklen_t)(sizeof ucred);
rc = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &length);
- if (rc < 0 || length != (socklen_t)(sizeof ucred)) {
+ if (rc < 0 || length != (socklen_t)(sizeof ucred) || !~ucred.uid) {
+#if !defined(NO_DEFAULT_PEERCRED)
+ ucred.uid = DEFAULT_PEERCRED_UID;
+ ucred.gid = DEFAULT_PEERCRED_GID;
+ ucred.pid = DEFAULT_PEERCRED_PID;
+#else
if (!rc)
errno = EINVAL;
return NULL;
+#endif
}
/* get the security label */
length = (socklen_t)(sizeof label);
rc = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, label, &length);
if (rc < 0 || length > (socklen_t)(sizeof label)) {
+#if !defined(NO_DEFAULT_PEERSEC)
+ length = (socklen_t)strlen(DEFAULT_PEERSEC_LABEL);
+ strcpy (label, DEFAULT_PEERSEC_LABEL);
+#else
if (!rc)
errno = EINVAL;
return NULL;
+#endif
}
/* makes the result */