// File: AGWA[P]logmailer/logmailer.cpp
// Function: drop_privileges(char const*, char const*)
static void drop_privileges (const char* username, const char* groupname)
{
	if (!username && !groupname) {
		return;
	}

	struct passwd*		usr = NULL;
	struct group*		grp = NULL;
	if (username) {
		errno = 0;
		if (!(usr = getpwnam(username))) {
			throw System_error("getpwnam", username, errno ? errno : ENOENT);
		}
	}

	if (groupname) {
		errno = 0;
		if (!(grp = getgrnam(groupname))) {
			throw System_error("getgrnam", groupname, errno ? errno : ENOENT);
		}
	}

	// If no group is specified, but a user is specified, drop to the primary GID of that user
	if (setgid(grp ? grp->gr_gid : usr->pw_gid) == -1) {
		throw System_error("setgid", "", errno);
	}

	if (usr) {
		if (initgroups(usr->pw_name, usr->pw_gid) == -1) {
			throw System_error("initgroups", usr->pw_name, errno);
		}
		if (setuid(usr->pw_uid) == -1) {
			throw System_error("setuid", usr->pw_name, errno);
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x270, %rsp            # imm = 0x270
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpq $0x0, -0x8(%rbp)
jne 0x3e26
cmpq $0x0, -0x10(%rbp)
jne 0x3e26
jmp 0x455a
movq $0x0, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0x3fa1
callq 0x3030
movl $0x0, (%rax)
movq -0x8(%rbp), %rdi
callq 0x3200
movq %rax, -0x18(%rbp)
cmpq $0x0, %rax
jne 0x3f9f
movb $0x1, -0x7a(%rbp)
movl $0x48, %edi
callq 0x3160
movq %rax, -0x1d0(%rbp)
leaq -0x41(%rbp), %rdi
movq %rdi, -0x1c8(%rbp)
callq 0x3510
movq -0x1c8(%rbp), %rdx
leaq 0x3358(%rip), %rsi      # 0x71ee
leaq -0x40(%rbp), %rdi
callq 0x5dd0
jmp 0x3ea1
movq -0x8(%rbp), %rax
movq %rax, -0x1e0(%rbp)
leaq -0x79(%rbp), %rdi
movq %rdi, -0x1d8(%rbp)
callq 0x3510
movq -0x1e0(%rbp), %rsi
movq -0x1d8(%rbp), %rdx
leaq -0x78(%rbp), %rdi
callq 0x5dd0
jmp 0x3ed5
callq 0x3030
cmpl $0x0, (%rax)
je 0x3eee
callq 0x3030
movl (%rax), %eax
movl %eax, -0x1e4(%rbp)
jmp 0x3efb
movl $0x2, %eax
movl %eax, -0x1e4(%rbp)
jmp 0x3efb
movq -0x1d0(%rbp), %rdi
movl -0x1e4(%rbp), %ecx
leaq -0x40(%rbp), %rsi
leaq -0x78(%rbp), %rdx
callq 0x5e80
jmp 0x3f17
movq -0x1d0(%rbp), %rdi
movb $0x0, -0x7a(%rbp)
leaq 0x4e5f(%rip), %rsi      # 0x8d88
leaq 0x1fc0(%rip), %rdx      # 0x5ef0
callq 0x34e0
jmp 0x456c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x3f7d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x3f6b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x3588
leaq -0x79(%rbp), %rdi
callq 0x32f0
leaq -0x40(%rbp), %rdi
callq 0x3588
leaq -0x41(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x7a(%rbp)
jne 0x3f8e
jmp 0x3f9a
movq -0x1d0(%rbp), %rdi
callq 0x31c0
jmp 0x4563
jmp 0x3fa1
cmpq $0x0, -0x10(%rbp)
je 0x4133
callq 0x3030
movl $0x0, (%rax)
movq -0x10(%rbp), %rdi
callq 0x3280
movq %rax, -0x20(%rbp)
cmpq $0x0, %rax
jne 0x4131
movb $0x1, -0xca(%rbp)
movl $0x48, %edi
callq 0x3160
movq %rax, -0x1f8(%rbp)
leaq -0xa1(%rbp), %rdi
movq %rdi, -0x1f0(%rbp)
callq 0x3510
movq -0x1f0(%rbp), %rdx
leaq 0x31f0(%rip), %rsi      # 0x71f7
leaq -0xa0(%rbp), %rdi
callq 0x5dd0
jmp 0x4015
movq -0x10(%rbp), %rax
movq %rax, -0x208(%rbp)
leaq -0xc9(%rbp), %rdi
movq %rdi, -0x200(%rbp)
callq 0x3510
movq -0x208(%rbp), %rsi
movq -0x200(%rbp), %rdx
leaq -0xc8(%rbp), %rdi
callq 0x5dd0
jmp 0x404f
callq 0x3030
cmpl $0x0, (%rax)
je 0x4068
callq 0x3030
movl (%rax), %eax
movl %eax, -0x20c(%rbp)
jmp 0x4075
movl $0x2, %eax
movl %eax, -0x20c(%rbp)
jmp 0x4075
movq -0x1f8(%rbp), %rdi
movl -0x20c(%rbp), %ecx
leaq -0xa0(%rbp), %rsi
leaq -0xc8(%rbp), %rdx
callq 0x5e80
jmp 0x4097
movq -0x1f8(%rbp), %rdi
movb $0x0, -0xca(%rbp)
leaq 0x4cdc(%rip), %rsi      # 0x8d88
leaq 0x1e3d(%rip), %rdx      # 0x5ef0
callq 0x34e0
jmp 0x456c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x4109
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x40f1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x3588
leaq -0xc9(%rbp), %rdi
callq 0x32f0
leaq -0xa0(%rbp), %rdi
callq 0x3588
leaq -0xa1(%rbp), %rdi
callq 0x32f0
testb $0x1, -0xca(%rbp)
jne 0x4120
jmp 0x412c
movq -0x1f8(%rbp), %rdi
callq 0x31c0
jmp 0x4563
jmp 0x4133
cmpq $0x0, -0x20(%rbp)
je 0x4149
movq -0x20(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x210(%rbp)
jmp 0x4156
movq -0x18(%rbp), %rax
movl 0x14(%rax), %eax
movl %eax, -0x210(%rbp)
movl -0x210(%rbp), %edi
callq 0x3520
cmpl $-0x1, %eax
jne 0x429d
movb $0x1, -0x11a(%rbp)
movl $0x48, %edi
callq 0x3160
movq %rax, -0x220(%rbp)
leaq -0xf1(%rbp), %rdi
movq %rdi, -0x218(%rbp)
callq 0x3510
movq -0x218(%rbp), %rdx
leaq 0x305d(%rip), %rsi      # 0x7200
leaq -0xf0(%rbp), %rdi
callq 0x5dd0
jmp 0x41b1
leaq -0x119(%rbp), %rdi
movq %rdi, -0x228(%rbp)
callq 0x3510
movq -0x228(%rbp), %rdx
leaq 0x307f(%rip), %rsi      # 0x7251
leaq -0x118(%rbp), %rdi
callq 0x5dd0
jmp 0x41e0
callq 0x3030
movq -0x220(%rbp), %rdi
movl (%rax), %ecx
leaq -0xf0(%rbp), %rsi
leaq -0x118(%rbp), %rdx
callq 0x5e80
jmp 0x4203
movq -0x220(%rbp), %rdi
movb $0x0, -0x11a(%rbp)
leaq 0x4b70(%rip), %rsi      # 0x8d88
leaq 0x1cd1(%rip), %rdx      # 0x5ef0
callq 0x34e0
jmp 0x456c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x4275
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x425d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x3588
leaq -0x119(%rbp), %rdi
callq 0x32f0
leaq -0xf0(%rbp), %rdi
callq 0x3588
leaq -0xf1(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x11a(%rbp)
jne 0x428c
jmp 0x4298
movq -0x220(%rbp), %rdi
callq 0x31c0
jmp 0x4563
cmpq $0x0, -0x18(%rbp)
je 0x455a
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movq -0x18(%rbp), %rax
movl 0x14(%rax), %esi
callq 0x3390
cmpl $-0x1, %eax
jne 0x4405
movb $0x1, -0x16a(%rbp)
movl $0x48, %edi
callq 0x3160
movq %rax, -0x238(%rbp)
leaq -0x141(%rbp), %rdi
movq %rdi, -0x230(%rbp)
callq 0x3510
movq -0x230(%rbp), %rdx
leaq 0x2f0a(%rip), %rsi      # 0x7207
leaq -0x140(%rbp), %rdi
callq 0x5dd0
jmp 0x430b
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x248(%rbp)
leaq -0x169(%rbp), %rdi
movq %rdi, -0x240(%rbp)
callq 0x3510
movq -0x248(%rbp), %rsi
movq -0x240(%rbp), %rdx
leaq -0x168(%rbp), %rdi
callq 0x5dd0
jmp 0x4348
callq 0x3030
movq -0x238(%rbp), %rdi
movl (%rax), %ecx
leaq -0x140(%rbp), %rsi
leaq -0x168(%rbp), %rdx
callq 0x5e80
jmp 0x436b
movq -0x238(%rbp), %rdi
movb $0x0, -0x16a(%rbp)
leaq 0x4a08(%rip), %rsi      # 0x8d88
leaq 0x1b69(%rip), %rdx      # 0x5ef0
callq 0x34e0
jmp 0x456c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x43dd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x43c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x3588
leaq -0x169(%rbp), %rdi
callq 0x32f0
leaq -0x140(%rbp), %rdi
callq 0x3588
leaq -0x141(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x16a(%rbp)
jne 0x43f4
jmp 0x4400
movq -0x238(%rbp), %rdi
callq 0x31c0
jmp 0x4563
movq -0x18(%rbp), %rax
movl 0x10(%rax), %edi
callq 0x3540
cmpl $-0x1, %eax
jne 0x4558
movb $0x1, -0x1ba(%rbp)
movl $0x48, %edi
callq 0x3160
movq %rax, -0x258(%rbp)
leaq -0x191(%rbp), %rdi
movq %rdi, -0x250(%rbp)
callq 0x3510
movq -0x250(%rbp), %rdx
leaq 0x2dbf(%rip), %rsi      # 0x7212
leaq -0x190(%rbp), %rdi
callq 0x5dd0
jmp 0x4461
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x268(%rbp)
leaq -0x1b9(%rbp), %rdi
movq %rdi, -0x260(%rbp)
callq 0x3510
movq -0x268(%rbp), %rsi
movq -0x260(%rbp), %rdx
leaq -0x1b8(%rbp), %rdi
callq 0x5dd0
jmp 0x449e
callq 0x3030
movq -0x258(%rbp), %rdi
movl (%rax), %ecx
leaq -0x190(%rbp), %rsi
leaq -0x1b8(%rbp), %rdx
callq 0x5e80
jmp 0x44c1
movq -0x258(%rbp), %rdi
movb $0x0, -0x1ba(%rbp)
leaq 0x48b2(%rip), %rsi      # 0x8d88
leaq 0x1a13(%rip), %rdx      # 0x5ef0
callq 0x34e0
jmp 0x456c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x4533
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x451b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x1b8(%rbp), %rdi
callq 0x3588
leaq -0x1b9(%rbp), %rdi
callq 0x32f0
leaq -0x190(%rbp), %rdi
callq 0x3588
leaq -0x191(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x1ba(%rbp)
jne 0x454a
jmp 0x4556
movq -0x258(%rbp), %rdi
callq 0x31c0
jmp 0x4563
jmp 0x455a
addq $0x270, %rsp            # imm = 0x270
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x3500
nopl (%rax)